From 0326e1c745710ddbb8f1d5e48fdb8eeff18a536a Mon Sep 17 00:00:00 2001 From: Jasper Siepkes Date: Thu, 5 Jul 2018 14:35:18 +0200 Subject: Add support for Solaris / Illumos. --- absl/base/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index 2f5f1595..6890e313 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -268,7 +268,7 @@ #error ABSL_HAVE_MMAP cannot be directly set #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \ - defined(__wasm__) || defined(__Fuchsia__) + defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) #define ABSL_HAVE_MMAP 1 #endif -- cgit v1.2.3 From bed5bd6e185c7e0311f3a1f2dab4c96083dac636 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 21 Aug 2018 11:31:02 -0700 Subject: Export of internal Abseil changes. -- f4bb8afa9376b4120f56f3beff7b07260da4a5c2 by CJ Johnson : Add user to Github list PiperOrigin-RevId: 209630262 GitOrigin-RevId: f4bb8afa9376b4120f56f3beff7b07260da4a5c2 Change-Id: I3fedf35011d805ee4a20b92e073b43523b47d15b --- absl/base/attributes.h | 2 +- absl/base/config.h | 2 +- absl/base/exception_safety_testing_test.cc | 2 +- absl/base/internal/raw_logging.h | 2 +- absl/base/log_severity.h | 2 +- absl/base/raw_logging_test.cc | 2 +- absl/container/inlined_vector_benchmark.cc | 2 +- absl/debugging/internal/demangle.cc | 4 +- absl/debugging/symbolize_test.cc | 2 +- absl/strings/ascii.h | 10 +-- absl/strings/charconv.h | 6 +- absl/strings/charconv_test.cc | 6 +- absl/strings/escaping.cc | 10 +-- absl/strings/escaping.h | 24 +++---- absl/strings/internal/charconv_parse.cc | 2 +- absl/strings/internal/charconv_parse_test.cc | 16 ++--- absl/strings/internal/memutil.h | 8 +-- absl/strings/internal/ostringstream.h | 12 ++-- absl/strings/internal/resize_uninitialized.h | 6 +- absl/strings/internal/str_format/bind.h | 2 +- absl/strings/internal/str_format/extension.h | 2 +- absl/strings/internal/str_format/parser.h | 6 +- absl/strings/internal/str_join_internal.h | 12 ++-- absl/strings/internal/str_split_internal.h | 4 +- absl/strings/match.h | 12 ++-- absl/strings/numbers.cc | 6 +- absl/strings/numbers.h | 18 +++--- absl/strings/numbers_benchmark.cc | 2 +- absl/strings/numbers_test.cc | 2 +- absl/strings/str_cat.cc | 6 +- absl/strings/str_cat.h | 26 ++++---- absl/strings/str_format.h | 78 +++++++++++------------ absl/strings/str_join.h | 56 ++++++++-------- absl/strings/str_replace.h | 28 ++++---- absl/strings/str_replace_benchmark.cc | 8 +-- absl/strings/str_split.h | 62 +++++++++--------- absl/strings/str_split_test.cc | 4 +- absl/strings/string_view.h | 16 ++--- absl/strings/string_view_test.cc | 4 +- absl/strings/strip.h | 18 +++--- absl/strings/strip_test.cc | 4 +- absl/strings/substitute.h | 36 +++++------ absl/synchronization/mutex.cc | 6 +- absl/synchronization/mutex.h | 2 +- absl/time/duration.cc | 14 ++-- absl/time/format.cc | 2 +- absl/time/internal/cctz/include/cctz/civil_time.h | 2 +- absl/time/internal/cctz/include/cctz/time_zone.h | 8 +-- absl/time/internal/cctz/src/time_zone_format.cc | 2 +- absl/time/internal/cctz/src/time_zone_info.cc | 2 +- absl/time/internal/cctz/src/time_zone_posix.h | 2 +- absl/time/time.h | 24 +++---- absl/types/span.h | 2 +- absl/utility/utility.h | 6 +- 54 files changed, 302 insertions(+), 302 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/attributes.h b/absl/base/attributes.h index b1883b6d..3662f0fe 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -100,7 +100,7 @@ // ABSL_PRINTF_ATTRIBUTE // ABSL_SCANF_ATTRIBUTE // -// Tells the compiler to perform `printf` format std::string checking if the +// Tells the compiler to perform `printf` format string checking if the // compiler supports it; see the 'format' attribute in // . // diff --git a/absl/base/config.h b/absl/base/config.h index 6890e313..035bd03f 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -199,7 +199,7 @@ #define ABSL_HAVE_INTRINSIC_INT128 1 #elif defined(__CUDACC__) // __CUDACC_VER__ is a full version number before CUDA 9, and is defined to a -// std::string explaining that it has been removed starting with CUDA 9. We use +// string explaining that it has been removed starting with CUDA 9. We use // nested #ifs because there is no short-circuiting in the preprocessor. // NOTE: `__CUDACC__` could be undefined while `__CUDACC_VER__` is defined. #if __CUDACC_VER__ >= 70000 diff --git a/absl/base/exception_safety_testing_test.cc b/absl/base/exception_safety_testing_test.cc index 724c0ad5..c2922f33 100644 --- a/absl/base/exception_safety_testing_test.cc +++ b/absl/base/exception_safety_testing_test.cc @@ -179,7 +179,7 @@ TEST(ThrowingValueTest, ThrowingStreamOps) { } // Tests the operator<< of ThrowingValue by forcing ConstructorTracker to emit -// a nonfatal failure that contains the std::string representation of the Thrower +// a nonfatal failure that contains the string representation of the Thrower TEST(ThrowingValueTest, StreamOpsOutput) { using ::testing::TypeSpec; exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h index 67abfd30..79a7bb9b 100644 --- a/absl/base/internal/raw_logging.h +++ b/absl/base/internal/raw_logging.h @@ -114,7 +114,7 @@ void SafeWriteToStderr(const char *s, size_t len); // compile-time function to get the "base" filename, that is, the part of // a filename after the last "/" or "\" path separator. The search starts at -// the end of the std::string; the second parameter is the length of the std::string. +// the end of the string; the second parameter is the length of the string. constexpr const char* Basename(const char* fname, int offset) { return offset == 0 || fname[offset - 1] == '/' || fname[offset - 1] == '\\' ? fname + offset diff --git a/absl/base/log_severity.h b/absl/base/log_severity.h index e2931c34..5770d362 100644 --- a/absl/base/log_severity.h +++ b/absl/base/log_severity.h @@ -39,7 +39,7 @@ constexpr std::array LogSeverities() { absl::LogSeverity::kError, absl::LogSeverity::kFatal}}; } -// Returns the all-caps std::string representation (e.g. "INFO") of the specified +// Returns the all-caps string representation (e.g. "INFO") of the specified // severity level if it is one of the normal levels and "UNKNOWN" otherwise. constexpr const char* LogSeverityName(absl::LogSeverity s) { return s == absl::LogSeverity::kInfo diff --git a/absl/base/raw_logging_test.cc b/absl/base/raw_logging_test.cc index ebbc5db9..b21cf651 100644 --- a/absl/base/raw_logging_test.cc +++ b/absl/base/raw_logging_test.cc @@ -40,7 +40,7 @@ TEST(RawLoggingCompilationTest, PassingCheck) { } // Not all platforms support output from raw log, so we don't verify any -// particular output for RAW check failures (expecting the empty std::string +// particular output for RAW check failures (expecting the empty string // accomplishes this). This test is primarily a compilation test, but we // are verifying process death when EXPECT_DEATH works for a platform. const char kExpectedDeathOutput[] = ""; diff --git a/absl/container/inlined_vector_benchmark.cc b/absl/container/inlined_vector_benchmark.cc index 24f21749..a3ad0f8a 100644 --- a/absl/container/inlined_vector_benchmark.cc +++ b/absl/container/inlined_vector_benchmark.cc @@ -66,7 +66,7 @@ BENCHMARK(BM_StdVectorFill)->Range(0, 1024); // The purpose of the next two benchmarks is to verify that // absl::InlinedVector is efficient when moving is more efficent than // copying. To do so, we use strings that are larger than the short -// std::string optimization. +// string optimization. bool StringRepresentedInline(std::string s) { const char* chars = s.data(); std::string s1 = std::move(s); diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index c9ca2f3b..48354459 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -340,7 +340,7 @@ static bool ZeroOrMore(ParseFunc parse_func, State *state) { } // Append "str" at "out_cur_idx". If there is an overflow, out_cur_idx is -// set to out_end_idx+1. The output std::string is ensured to +// set to out_end_idx+1. The output string is ensured to // always terminate with '\0' as long as there is no overflow. static void Append(State *state, const char *const str, const int length) { for (int i = 0; i < length; ++i) { @@ -840,7 +840,7 @@ static bool ParseNumber(State *state, int *number_out) { } // Floating-point literals are encoded using a fixed-length lowercase -// hexadecimal std::string. +// hexadecimal string. static bool ParseFloatNumber(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc index 5f2af47e..8029fbe9 100644 --- a/absl/debugging/symbolize_test.cc +++ b/absl/debugging/symbolize_test.cc @@ -321,7 +321,7 @@ TEST(Symbolize, SymbolizeWithMultipleMaps) { } } -// Appends std::string(*args->arg) to args->symbol_buf. +// Appends string(*args->arg) to args->symbol_buf. static void DummySymbolDecorator( const absl::debugging_internal::SymbolDecoratorArgs *args) { std::string *message = static_cast(args->arg); diff --git a/absl/strings/ascii.h b/absl/strings/ascii.h index 96a64541..4195d093 100644 --- a/absl/strings/ascii.h +++ b/absl/strings/ascii.h @@ -165,7 +165,7 @@ inline char ascii_tolower(unsigned char c) { // Converts the characters in `s` to lowercase, changing the contents of `s`. void AsciiStrToLower(std::string* s); -// Creates a lowercase std::string from a given absl::string_view. +// Creates a lowercase string from a given absl::string_view. ABSL_MUST_USE_RESULT inline std::string AsciiStrToLower(absl::string_view s) { std::string result(s); absl::AsciiStrToLower(&result); @@ -183,7 +183,7 @@ inline char ascii_toupper(unsigned char c) { // Converts the characters in `s` to uppercase, changing the contents of `s`. void AsciiStrToUpper(std::string* s); -// Creates an uppercase std::string from a given absl::string_view. +// Creates an uppercase string from a given absl::string_view. ABSL_MUST_USE_RESULT inline std::string AsciiStrToUpper(absl::string_view s) { std::string result(s); absl::AsciiStrToUpper(&result); @@ -198,7 +198,7 @@ ABSL_MUST_USE_RESULT inline absl::string_view StripLeadingAsciiWhitespace( return absl::string_view(it, str.end() - it); } -// Strips in place whitespace from the beginning of the given std::string. +// Strips in place whitespace from the beginning of the given string. inline void StripLeadingAsciiWhitespace(std::string* str) { auto it = std::find_if_not(str->begin(), str->end(), absl::ascii_isspace); str->erase(str->begin(), it); @@ -212,7 +212,7 @@ ABSL_MUST_USE_RESULT inline absl::string_view StripTrailingAsciiWhitespace( return absl::string_view(str.begin(), str.rend() - it); } -// Strips in place whitespace from the end of the given std::string +// Strips in place whitespace from the end of the given string inline void StripTrailingAsciiWhitespace(std::string* str) { auto it = std::find_if_not(str->rbegin(), str->rend(), absl::ascii_isspace); str->erase(str->rend() - it); @@ -225,7 +225,7 @@ ABSL_MUST_USE_RESULT inline absl::string_view StripAsciiWhitespace( return StripTrailingAsciiWhitespace(StripLeadingAsciiWhitespace(str)); } -// Strips in place whitespace from both ends of the given std::string +// Strips in place whitespace from both ends of the given string inline void StripAsciiWhitespace(std::string* str) { StripTrailingAsciiWhitespace(str); StripLeadingAsciiWhitespace(str); diff --git a/absl/strings/charconv.h b/absl/strings/charconv.h index 3e313679..07353829 100644 --- a/absl/strings/charconv.h +++ b/absl/strings/charconv.h @@ -22,7 +22,7 @@ namespace absl { // Workalike compatibilty version of std::chars_format from C++17. // // This is an bitfield enumerator which can be passed to absl::from_chars to -// configure the std::string-to-float conversion. +// configure the string-to-float conversion. enum class chars_format { scientific = 1, fixed = 2, @@ -30,7 +30,7 @@ enum class chars_format { general = fixed | scientific, }; -// The return result of a std::string-to-number conversion. +// The return result of a string-to-number conversion. // // `ec` will be set to `invalid_argument` if a well-formed number was not found // at the start of the input range, `result_out_of_range` if a well-formed @@ -67,7 +67,7 @@ struct from_chars_result { // If `fmt` is set, it must be one of the enumerator values of the chars_format. // (This is despite the fact that chars_format is a bitmask type.) If set to // `scientific`, a matching number must contain an exponent. If set to `fixed`, -// then an exponent will never match. (For example, the std::string "1e5" will be +// then an exponent will never match. (For example, the string "1e5" will be // parsed as "1".) If set to `hex`, then a hexadecimal float is parsed in the // format that strtod() accepts, except that a "0x" prefix is NOT matched. // (In particular, in `hex` mode, the input "0xff" results in the largest diff --git a/absl/strings/charconv_test.cc b/absl/strings/charconv_test.cc index f8d71cc6..89418fe9 100644 --- a/absl/strings/charconv_test.cc +++ b/absl/strings/charconv_test.cc @@ -33,7 +33,7 @@ namespace { #if ABSL_COMPILER_DOES_EXACT_ROUNDING -// Tests that the given std::string is accepted by absl::from_chars, and that it +// Tests that the given string is accepted by absl::from_chars, and that it // converts exactly equal to the given number. void TestDoubleParse(absl::string_view str, double expected_number) { SCOPED_TRACE(str); @@ -250,7 +250,7 @@ TEST(FromChars, NearRoundingCasesExplicit) { EXPECT_EQ(ToFloat("459926601011.e15"), ldexpf(12466336, 65)); } -// Common test logic for converting a std::string which lies exactly halfway between +// Common test logic for converting a string which lies exactly halfway between // two target floats. // // mantissa and exponent represent the precise value between two floating point @@ -655,7 +655,7 @@ int NextStep(int step) { // is correct for in-bounds values, and that overflow and underflow are done // correctly for out-of-bounds values. // -// input_generator maps from an integer index to a std::string to test. +// input_generator maps from an integer index to a string to test. // expected_generator maps from an integer index to an expected Float value. // from_chars conversion of input_generator(i) should result in // expected_generator(i). diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc index fbc9f756..c8f18d86 100644 --- a/absl/strings/escaping.cc +++ b/absl/strings/escaping.cc @@ -89,7 +89,7 @@ inline bool IsSurrogate(char32_t c, absl::string_view src, std::string* error) { // // Unescapes C escape sequences and is the reverse of CEscape(). // -// If 'source' is valid, stores the unescaped std::string and its size in +// If 'source' is valid, stores the unescaped string and its size in // 'dest' and 'dest_len' respectively, and returns true. Otherwise // returns false and optionally stores the error description in // 'error'. Set 'error' to nullptr to disable error reporting. @@ -294,7 +294,7 @@ bool CUnescapeInternal(absl::string_view source, bool leave_nulls_escaped, // ---------------------------------------------------------------------- // CUnescapeInternal() // -// Same as above but uses a C++ std::string for output. 'source' and 'dest' +// Same as above but uses a C++ string for output. 'source' and 'dest' // may be the same. // ---------------------------------------------------------------------- bool CUnescapeInternal(absl::string_view source, bool leave_nulls_escaped, @@ -684,7 +684,7 @@ bool Base64UnescapeInternal(const char* src_param, size_t szsrc, char* dest, // The arrays below were generated by the following code // #include // #include -// #include +// #include // main() // { // static const char Base64[] = @@ -999,7 +999,7 @@ constexpr char kHexValue[256] = { /* clang-format on */ // This is a templated function so that T can be either a char* -// or a std::string. This works because we use the [] operator to access +// or a string. This works because we use the [] operator to access // individual characters at a time. template void HexStringToBytesInternal(const char* from, T to, ptrdiff_t num) { @@ -1009,7 +1009,7 @@ void HexStringToBytesInternal(const char* from, T to, ptrdiff_t num) { } } -// This is a templated function so that T can be either a char* or a std::string. +// This is a templated function so that T can be either a char* or a string. template void BytesToHexStringInternal(const unsigned char* src, T dest, ptrdiff_t num) { auto dest_ptr = &dest[0]; diff --git a/absl/strings/escaping.h b/absl/strings/escaping.h index 5a13b1fb..beb67a27 100644 --- a/absl/strings/escaping.h +++ b/absl/strings/escaping.h @@ -17,7 +17,7 @@ // File: escaping.h // ----------------------------------------------------------------------------- // -// This header file contains std::string utilities involved in escaping and +// This header file contains string utilities involved in escaping and // unescaping strings in various ways. // @@ -37,7 +37,7 @@ namespace absl { // CUnescape() // -// Unescapes a `source` std::string and copies it into `dest`, rewriting C-style +// Unescapes a `source` string and copies it into `dest`, rewriting C-style // escape sequences (http://en.cppreference.com/w/cpp/language/escape) into // their proper code point equivalents, returning `true` if successful. // @@ -78,7 +78,7 @@ inline bool CUnescape(absl::string_view source, std::string* dest) { // CEscape() // -// Escapes a 'src' std::string using C-style escapes sequences +// Escapes a 'src' string using C-style escapes sequences // (http://en.cppreference.com/w/cpp/language/escape), escaping other // non-printable/non-whitespace bytes as octal sequences (e.g. "\377"). // @@ -91,7 +91,7 @@ std::string CEscape(absl::string_view src); // CHexEscape() // -// Escapes a 'src' std::string using C-style escape sequences, escaping +// Escapes a 'src' string using C-style escape sequences, escaping // other non-printable/non-whitespace bytes as hexadecimal sequences (e.g. // "\xFF"). // @@ -104,7 +104,7 @@ std::string CHexEscape(absl::string_view src); // Utf8SafeCEscape() // -// Escapes a 'src' std::string using C-style escape sequences, escaping bytes as +// Escapes a 'src' string using C-style escape sequences, escaping bytes as // octal sequences, and passing through UTF-8 characters without conversion. // I.e., when encountering any bytes with their high bit set, this function // will not escape those values, whether or not they are valid UTF-8. @@ -112,47 +112,47 @@ std::string Utf8SafeCEscape(absl::string_view src); // Utf8SafeCHexEscape() // -// Escapes a 'src' std::string using C-style escape sequences, escaping bytes as +// Escapes a 'src' string using C-style escape sequences, escaping bytes as // hexadecimal sequences, and passing through UTF-8 characters without // conversion. std::string Utf8SafeCHexEscape(absl::string_view src); // Base64Unescape() // -// Converts a `src` std::string encoded in Base64 to its binary equivalent, writing +// Converts a `src` string encoded in Base64 to its binary equivalent, writing // it to a `dest` buffer, returning `true` on success. If `src` contains invalid // characters, `dest` is cleared and returns `false`. bool Base64Unescape(absl::string_view src, std::string* dest); // WebSafeBase64Unescape() // -// Converts a `src` std::string encoded in Base64 to its binary equivalent, writing +// Converts a `src` string encoded in Base64 to its binary equivalent, writing // it to a `dest` buffer, but using '-' instead of '+', and '_' instead of '/'. // If `src` contains invalid characters, `dest` is cleared and returns `false`. bool WebSafeBase64Unescape(absl::string_view src, std::string* dest); // Base64Escape() // -// Encodes a `src` std::string into a `dest` buffer using base64 encoding, with +// Encodes a `src` string into a `dest` buffer using base64 encoding, with // padding characters. This function conforms with RFC 4648 section 4 (base64). void Base64Escape(absl::string_view src, std::string* dest); // WebSafeBase64Escape() // -// Encodes a `src` std::string into a `dest` buffer using '-' instead of '+' and +// Encodes a `src` string into a `dest` buffer using '-' instead of '+' and // '_' instead of '/', and without padding. This function conforms with RFC 4648 // section 5 (base64url). void WebSafeBase64Escape(absl::string_view src, std::string* dest); // HexStringToBytes() // -// Converts an ASCII hex std::string into bytes, returning binary data of length +// Converts an ASCII hex string into bytes, returning binary data of length // `from.size()/2`. std::string HexStringToBytes(absl::string_view from); // BytesToHexString() // -// Converts binary data into an ASCII text std::string, returning a std::string of size +// Converts binary data into an ASCII text string, returning a string of size // `2*from.size()`. std::string BytesToHexString(absl::string_view from); diff --git a/absl/strings/internal/charconv_parse.cc b/absl/strings/internal/charconv_parse.cc index a04cc676..7e4dabc2 100644 --- a/absl/strings/internal/charconv_parse.cc +++ b/absl/strings/internal/charconv_parse.cc @@ -91,7 +91,7 @@ static_assert(std::numeric_limits::digits10 >= kDecimalExponentDigitsMax, // To avoid incredibly large inputs causing integer overflow for our exponent, // we impose an arbitrary but very large limit on the number of significant -// digits we will accept. The implementation refuses to match a std::string with +// digits we will accept. The implementation refuses to match a string with // more consecutive significant mantissa digits than this. constexpr int kDecimalDigitLimit = 50000000; diff --git a/absl/strings/internal/charconv_parse_test.cc b/absl/strings/internal/charconv_parse_test.cc index 1ff86004..f48b9aee 100644 --- a/absl/strings/internal/charconv_parse_test.cc +++ b/absl/strings/internal/charconv_parse_test.cc @@ -29,16 +29,16 @@ using absl::strings_internal::ParseFloat; namespace { -// Check that a given std::string input is parsed to the expected mantissa and +// Check that a given string input is parsed to the expected mantissa and // exponent. // -// Input std::string `s` must contain a '$' character. It marks the end of the +// Input string `s` must contain a '$' character. It marks the end of the // characters that should be consumed by the match. It is stripped from the // input to ParseFloat. // -// If input std::string `s` contains '[' and ']' characters, these mark the region +// If input string `s` contains '[' and ']' characters, these mark the region // of characters that should be marked as the "subrange". For NaNs, this is -// the location of the extended NaN std::string. For numbers, this is the location +// the location of the extended NaN string. For numbers, this is the location // of the full, over-large mantissa. template void ExpectParsedFloat(std::string s, absl::chars_format format_flags, @@ -92,10 +92,10 @@ void ExpectParsedFloat(std::string s, absl::chars_format format_flags, EXPECT_EQ(characters_matched, expected_characters_matched); } -// Check that a given std::string input is parsed to the expected mantissa and +// Check that a given string input is parsed to the expected mantissa and // exponent. // -// Input std::string `s` must contain a '$' character. It marks the end of the +// Input string `s` must contain a '$' character. It marks the end of the // characters that were consumed by the match. template void ExpectNumber(std::string s, absl::chars_format format_flags, @@ -106,7 +106,7 @@ void ExpectNumber(std::string s, absl::chars_format format_flags, expected_literal_exponent); } -// Check that a given std::string input is parsed to the given special value. +// Check that a given string input is parsed to the given special value. // // This tests against both number bases, since infinities and NaNs have // identical representations in both modes. @@ -116,7 +116,7 @@ void ExpectSpecial(const std::string& s, absl::chars_format format_flags, ExpectParsedFloat<16>(s, format_flags, type, 0, 0); } -// Check that a given input std::string is not matched by Float. +// Check that a given input string is not matched by Float. template void ExpectFailedParse(absl::string_view s, absl::chars_format format_flags) { ParsedFloat parsed = diff --git a/absl/strings/internal/memutil.h b/absl/strings/internal/memutil.h index a6f1c691..7de383b1 100644 --- a/absl/strings/internal/memutil.h +++ b/absl/strings/internal/memutil.h @@ -14,7 +14,7 @@ // limitations under the License. // -// These routines provide mem versions of standard C std::string routines, +// These routines provide mem versions of standard C string routines, // such as strpbrk. They function exactly the same as the str versions, // so if you wonder what they are, replace the word "mem" by // "str" and check out the man page. I could return void*, as the @@ -22,14 +22,14 @@ // since this is by far the most common way these functions are called. // // The difference between the mem and str versions is the mem version -// takes a pointer and a length, rather than a '\0'-terminated std::string. +// takes a pointer and a length, rather than a '\0'-terminated string. // The memcase* routines defined here assume the locale is "C" // (they use absl::ascii_tolower instead of tolower). // // These routines are based on the BSD library. // -// Here's a list of routines from std::string.h, and their mem analogues. -// Functions in lowercase are defined in std::string.h; those in UPPERCASE +// Here's a list of routines from string.h, and their mem analogues. +// Functions in lowercase are defined in string.h; those in UPPERCASE // are defined here: // // strlen -- diff --git a/absl/strings/internal/ostringstream.h b/absl/strings/internal/ostringstream.h index 6e1325b9..e81a89af 100644 --- a/absl/strings/internal/ostringstream.h +++ b/absl/strings/internal/ostringstream.h @@ -25,18 +25,18 @@ namespace absl { namespace strings_internal { -// The same as std::ostringstream but appends to a user-specified std::string, +// The same as std::ostringstream but appends to a user-specified string, // and is faster. It is ~70% faster to create, ~50% faster to write to, and -// completely free to extract the result std::string. +// completely free to extract the result string. // -// std::string s; +// string s; // OStringStream strm(&s); // strm << 42 << ' ' << 3.14; // appends to `s` // // The stream object doesn't have to be named. Starting from C++11 operator<< // works with rvalues of std::ostream. // -// std::string s; +// string s; // OStringStream(&s) << 42 << ' ' << 3.14; // appends to `s` // // OStringStream is faster to create than std::ostringstream but it's still @@ -45,14 +45,14 @@ namespace strings_internal { // // Creates unnecessary instances of OStringStream: slow. // -// std::string s; +// string s; // OStringStream(&s) << 42; // OStringStream(&s) << ' '; // OStringStream(&s) << 3.14; // // Creates a single instance of OStringStream and reuses it: fast. // -// std::string s; +// string s; // OStringStream strm(&s); // strm << 42; // strm << ' '; diff --git a/absl/strings/internal/resize_uninitialized.h b/absl/strings/internal/resize_uninitialized.h index 0157ca02..a94e0547 100644 --- a/absl/strings/internal/resize_uninitialized.h +++ b/absl/strings/internal/resize_uninitialized.h @@ -44,8 +44,8 @@ void ResizeUninit(string_type* s, size_t new_size, std::false_type) { s->resize(new_size); } -// Returns true if the std::string implementation supports a resize where -// the new characters added to the std::string are left untouched. +// Returns true if the string implementation supports a resize where +// the new characters added to the string are left untouched. // // (A better name might be "STLStringSupportsUninitializedResize", alluding to // the previous function.) @@ -57,7 +57,7 @@ inline constexpr bool STLStringSupportsNontrashingResize(string_type*) { // Like str->resize(new_size), except any new characters added to "*str" as a // result of resizing may be left uninitialized, rather than being filled with // '0' bytes. Typically used when code is then going to overwrite the backing -// store of the std::string with known data. Uses a Google extension to std::string. +// store of the string with known data. Uses a Google extension to ::string. template inline void STLStringResizeUninitialized(string_type* s, size_t new_size) { ResizeUninit(s, new_size, HasResizeUninitialized()); diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h index 40086112..9d3d67c6 100644 --- a/absl/strings/internal/str_format/bind.h +++ b/absl/strings/internal/str_format/bind.h @@ -168,7 +168,7 @@ int FprintF(std::FILE* output, const UntypedFormatSpecImpl& format, int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl& format, absl::Span args); -// Returned by Streamed(v). Converts via '%s' to the std::string created +// Returned by Streamed(v). Converts via '%s' to the string created // by std::ostream << v. template class StreamedWrapper { diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index 810330b9..f43195c1 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h @@ -57,7 +57,7 @@ class FormatRawSinkImpl { void (*write_)(void*, string_view); }; -// An abstraction to which conversions write their std::string data. +// An abstraction to which conversions write their string data. class FormatSinkImpl { public: explicit FormatSinkImpl(FormatRawSinkImpl raw) : raw_(raw) {} diff --git a/absl/strings/internal/str_format/parser.h b/absl/strings/internal/str_format/parser.h index 5bebc955..7414e153 100644 --- a/absl/strings/internal/str_format/parser.h +++ b/absl/strings/internal/str_format/parser.h @@ -75,14 +75,14 @@ struct UnboundConversion { bool ConsumeUnboundConversion(string_view* src, UnboundConversion* conv, int* next_arg); -// Parse the format std::string provided in 'src' and pass the identified items into +// Parse the format string provided in 'src' and pass the identified items into // 'consumer'. // Text runs will be passed by calling // Consumer::Append(string_view); // ConversionItems will be passed by calling // Consumer::ConvertOne(UnboundConversion, string_view); // In the case of ConvertOne, the string_view that is passed is the -// portion of the format std::string corresponding to the conversion, not including +// portion of the format string corresponding to the conversion, not including // the leading %. On success, it returns true. On failure, it stops and returns // false. template @@ -237,7 +237,7 @@ class ParsedFormatBase { // This class also supports runtime format checking with the ::New() and // ::NewAllowIgnored() factory functions. // This is the only API that allows the user to pass a runtime specified format -// std::string. These factory functions will return NULL if the format does not match +// string. These factory functions will return NULL if the format does not match // the conversions requested by the user. template class ExtendedParsedFormat : public str_format_internal::ParsedFormatBase { diff --git a/absl/strings/internal/str_join_internal.h b/absl/strings/internal/str_join_internal.h index a734758c..0058fc8a 100644 --- a/absl/strings/internal/str_join_internal.h +++ b/absl/strings/internal/str_join_internal.h @@ -189,7 +189,7 @@ struct DefaultFormatter> // // The main joining algorithm. This simply joins the elements in the given -// iterator range, each separated by the given separator, into an output std::string, +// iterator range, each separated by the given separator, into an output string, // and formats each element using the provided Formatter object. template std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s, @@ -205,20 +205,20 @@ std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s, } // A joining algorithm that's optimized for a forward iterator range of -// std::string-like objects that do not need any additional formatting. This is to -// optimize the common case of joining, say, a std::vector or a +// string-like objects that do not need any additional formatting. This is to +// optimize the common case of joining, say, a std::vector or a // std::vector. // // This is an overload of the previous JoinAlgorithm() function. Here the // Formatter argument is of type NoFormatter. Since NoFormatter is an internal // type, this overload is only invoked when strings::Join() is called with a -// range of std::string-like objects (e.g., std::string, absl::string_view), and an +// range of string-like objects (e.g., string, absl::string_view), and an // explicit Formatter argument was NOT specified. // // The optimization is that the needed space will be reserved in the output -// std::string to avoid the need to resize while appending. To do this, the iterator +// string to avoid the need to resize while appending. To do this, the iterator // range will be traversed twice: once to calculate the total needed size, and -// then again to copy the elements and delimiters to the output std::string. +// then again to copy the elements and delimiters to the output string. template ::iterator_category, diff --git a/absl/strings/internal/str_split_internal.h b/absl/strings/internal/str_split_internal.h index 9cf0833f..73a30fdf 100644 --- a/absl/strings/internal/str_split_internal.h +++ b/absl/strings/internal/str_split_internal.h @@ -51,7 +51,7 @@ namespace strings_internal { // This class is implicitly constructible from everything that absl::string_view // is implicitly constructible from. If it's constructed from a temporary -// std::string, the data is moved into a data member so its lifetime matches that of +// string, the data is moved into a data member so its lifetime matches that of // the ConvertibleToStringView instance. class ConvertibleToStringView { public: @@ -102,7 +102,7 @@ ConvertibleToStringView(std::string&& s) // NOLINT(runtime/explicit) absl::string_view value_; }; -// An iterator that enumerates the parts of a std::string from a Splitter. The text +// An iterator that enumerates the parts of a string from a Splitter. The text // to be split, the Delimiter, and the Predicate are all taken from the given // Splitter object. Iterators may only be compared if they refer to the same // Splitter instance. diff --git a/absl/strings/match.h b/absl/strings/match.h index 108b6048..942a196b 100644 --- a/absl/strings/match.h +++ b/absl/strings/match.h @@ -17,7 +17,7 @@ // File: match.h // ----------------------------------------------------------------------------- // -// This file contains simple utilities for performing std::string matching checks. +// This file contains simple utilities for performing string matching checks. // All of these function parameters are specified as `absl::string_view`, // meaning that these functions can accept `std::string`, `absl::string_view` or // nul-terminated C-style strings. @@ -41,14 +41,14 @@ namespace absl { // StrContains() // -// Returns whether a given std::string `haystack` contains the substring `needle`. +// Returns whether a given string `haystack` contains the substring `needle`. inline bool StrContains(absl::string_view haystack, absl::string_view needle) { return haystack.find(needle, 0) != haystack.npos; } // StartsWith() // -// Returns whether a given std::string `text` begins with `prefix`. +// Returns whether a given string `text` begins with `prefix`. inline bool StartsWith(absl::string_view text, absl::string_view prefix) { return prefix.empty() || (text.size() >= prefix.size() && @@ -57,7 +57,7 @@ inline bool StartsWith(absl::string_view text, absl::string_view prefix) { // EndsWith() // -// Returns whether a given std::string `text` ends with `suffix`. +// Returns whether a given string `text` ends with `suffix`. inline bool EndsWith(absl::string_view text, absl::string_view suffix) { return suffix.empty() || (text.size() >= suffix.size() && @@ -68,13 +68,13 @@ inline bool EndsWith(absl::string_view text, absl::string_view suffix) { // StartsWithIgnoreCase() // -// Returns whether a given std::string `text` starts with `starts_with`, ignoring +// Returns whether a given string `text` starts with `starts_with`, ignoring // case in the comparison. bool StartsWithIgnoreCase(absl::string_view text, absl::string_view prefix); // EndsWithIgnoreCase() // -// Returns whether a given std::string `text` ends with `ends_with`, ignoring case +// Returns whether a given string `text` ends with `ends_with`, ignoring case // in the comparison. bool EndsWithIgnoreCase(absl::string_view text, absl::string_view suffix); diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index f842ed85..cc878f5b 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// This file contains std::string processing functions related to +// This file contains string processing functions related to // numeric values. #include "absl/strings/numbers.h" @@ -161,8 +161,8 @@ bool SimpleAtob(absl::string_view str, bool* value) { // their output to the beginning of the buffer. The caller is responsible // for ensuring that the buffer has enough space to hold the output. // -// Returns a pointer to the end of the std::string (i.e. the null character -// terminating the std::string). +// Returns a pointer to the end of the string (i.e. the null character +// terminating the string). // ---------------------------------------------------------------------- namespace { diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h index fbed273e..f9b2ccef 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -41,8 +41,8 @@ namespace absl { // SimpleAtoi() // -// Converts the given std::string into an integer value, returning `true` if -// successful. The std::string must reflect a base-10 integer (optionally followed or +// Converts the given string into an integer value, returning `true` if +// successful. The string must reflect a base-10 integer (optionally followed or // preceded by ASCII whitespace) whose value falls within the range of the // integer type. template @@ -50,23 +50,23 @@ ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out); // SimpleAtof() // -// Converts the given std::string (optionally followed or preceded by ASCII +// Converts the given string (optionally followed or preceded by ASCII // whitespace) into a float, which may be rounded on overflow or underflow. -// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the +// See http://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`. ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* value); // SimpleAtod() // -// Converts the given std::string (optionally followed or preceded by ASCII +// Converts the given string (optionally followed or preceded by ASCII // whitespace) into a double, which may be rounded on overflow or underflow. -// See http://en.cppreference.com/w/c/std::string/byte/strtof for details about the +// See http://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`. ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* value); // SimpleAtob() // -// Converts the given std::string into a boolean, returning `true` if successful. +// Converts the given string into a boolean, returning `true` if successful. // The following case-insensitive strings are interpreted as boolean `true`: // "true", "t", "yes", "y", "1". The following case-insensitive strings // are interpreted as boolean `false`: "false", "f", "no", "n", "0". @@ -169,9 +169,9 @@ ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s, int_type* out, // SimpleAtoi() // -// Converts a std::string to an integer, using `safe_strto?()` functions for actual +// Converts a string to an integer, using `safe_strto?()` functions for actual // parsing, returning `true` if successful. The `safe_strto?()` functions apply -// strict checking; the std::string must be a base-10 integer, optionally followed or +// strict checking; the string must be a base-10 integer, optionally followed or // preceded by ASCII whitespace, with a value in the range of the corresponding // integer type. template diff --git a/absl/strings/numbers_benchmark.cc b/absl/strings/numbers_benchmark.cc index 8ef650b9..0570b758 100644 --- a/absl/strings/numbers_benchmark.cc +++ b/absl/strings/numbers_benchmark.cc @@ -158,7 +158,7 @@ BENCHMARK(BM_safe_strtou64_string) ->ArgPair(16, 10) ->ArgPair(16, 16); -// Returns a vector of `num_strings` strings. Each std::string represents a +// Returns a vector of `num_strings` strings. Each string represents a // floating point number with `num_digits` digits before the decimal point and // another `num_digits` digits after. std::vector MakeFloatStrings(int num_strings, int num_digits) { diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index 27cc0479..36fc0d64 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// This file tests std::string processing functions related to numeric values. +// This file tests string processing functions related to numeric values. #include "absl/strings/numbers.h" diff --git a/absl/strings/str_cat.cc b/absl/strings/str_cat.cc index 3fe8c95e..efa4fd73 100644 --- a/absl/strings/str_cat.cc +++ b/absl/strings/str_cat.cc @@ -79,7 +79,7 @@ AlphaNum::AlphaNum(Dec dec) { // ---------------------------------------------------------------------- // StrCat() // This merges the given strings or integers, with no delimiter. This -// is designed to be the fastest possible way to construct a std::string out +// is designed to be the fastest possible way to construct a string out // of a mix of raw C strings, StringPieces, strings, and integer values. // ---------------------------------------------------------------------- @@ -154,10 +154,10 @@ std::string CatPieces(std::initializer_list pieces) { } // It's possible to call StrAppend with an absl::string_view that is itself a -// fragment of the std::string we're appending to. However the results of this are +// fragment of the string we're appending to. However the results of this are // random. Therefore, check for this in debug mode. Use unsigned math so we // only have to do one comparison. Note, there's an exception case: appending an -// empty std::string is always allowed. +// empty string is always allowed. #define ASSERT_NO_OVERLAP(dest, src) \ assert(((src).size() == 0) || \ (uintptr_t((src).data() - (dest).data()) > uintptr_t((dest).size()))) diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h index e5501a50..da9ed9a2 100644 --- a/absl/strings/str_cat.h +++ b/absl/strings/str_cat.h @@ -23,7 +23,7 @@ // designed to be used as a parameter type that efficiently manages conversion // to strings and avoids copies in the above operations. // -// Any routine accepting either a std::string or a number may accept `AlphaNum`. +// Any routine accepting either a string or a number may accept `AlphaNum`. // The basic idea is that by accepting a `const AlphaNum &` as an argument // to your function, your callers will automagically convert bools, integers, // and floating point values to strings for you. @@ -65,7 +65,7 @@ namespace absl { namespace strings_internal { -// AlphaNumBuffer allows a way to pass a std::string to StrCat without having to do +// AlphaNumBuffer allows a way to pass a string to StrCat without having to do // memory allocation. It is simply a pair of a fixed-size character array, and // a size. Please don't use outside of absl, yet. template @@ -119,8 +119,8 @@ enum PadSpec : uint8_t { // Hex // ----------------------------------------------------------------------------- // -// `Hex` stores a set of hexadecimal std::string conversion parameters for use -// within `AlphaNum` std::string conversions. +// `Hex` stores a set of hexadecimal string conversion parameters for use +// within `AlphaNum` string conversions. struct Hex { uint64_t value; uint8_t width; @@ -168,8 +168,8 @@ struct Hex { // Dec // ----------------------------------------------------------------------------- // -// `Dec` stores a set of decimal std::string conversion parameters for use -// within `AlphaNum` std::string conversions. Dec is slower than the default +// `Dec` stores a set of decimal string conversion parameters for use +// within `AlphaNum` string conversions. Dec is slower than the default // integer conversion, so use it only if you need padding. struct Dec { uint64_t value; @@ -271,7 +271,7 @@ class AlphaNum { // // Merges given strings or numbers, using no delimiter(s). // -// `StrCat()` is designed to be the fastest possible way to construct a std::string +// `StrCat()` is designed to be the fastest possible way to construct a string // out of a mix of raw C strings, string_views, strings, bool values, // and numeric values. // @@ -279,7 +279,7 @@ class AlphaNum { // works poorly on strings built up out of fragments. // // For clarity and performance, don't use `StrCat()` when appending to a -// std::string. Use `StrAppend()` instead. In particular, avoid using any of these +// string. Use `StrAppend()` instead. In particular, avoid using any of these // (anti-)patterns: // // str.append(StrCat(...)) @@ -328,26 +328,26 @@ ABSL_MUST_USE_RESULT inline std::string StrCat(const AlphaNum& a, const AlphaNum // StrAppend() // ----------------------------------------------------------------------------- // -// Appends a std::string or set of strings to an existing std::string, in a similar +// Appends a string or set of strings to an existing string, in a similar // fashion to `StrCat()`. // // WARNING: `StrAppend(&str, a, b, c, ...)` requires that none of the // a, b, c, parameters be a reference into str. For speed, `StrAppend()` does // not try to check each of its input arguments to be sure that they are not -// a subset of the std::string being appended to. That is, while this will work: +// a subset of the string being appended to. That is, while this will work: // -// std::string s = "foo"; +// string s = "foo"; // s += s; // // This output is undefined: // -// std::string s = "foo"; +// string s = "foo"; // StrAppend(&s, s); // // This output is undefined as well, since `absl::string_view` does not own its // data: // -// std::string s = "foobar"; +// string s = "foobar"; // absl::string_view p = s; // StrAppend(&s, p); diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index 9f44c713..2d07725d 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -18,20 +18,20 @@ // ----------------------------------------------------------------------------- // // The `str_format` library is a typesafe replacement for the family of -// `printf()` std::string formatting routines within the `` standard library +// `printf()` string formatting routines within the `` standard library // header. Like the `printf` family, the `str_format` uses a "format string" to // perform argument substitutions based on types. // // Example: // -// std::string s = absl::StrFormat("%s %s You have $%d!", "Hello", name, dollars); +// string s = absl::StrFormat("%s %s You have $%d!", "Hello", name, dollars); // // The library consists of the following basic utilities: // // * `absl::StrFormat()`, a type-safe replacement for `std::sprintf()`, to -// write a format std::string to a `string` value. -// * `absl::StrAppendFormat()` to append a format std::string to a `string` -// * `absl::StreamFormat()` to more efficiently write a format std::string to a +// write a format string to a `string` value. +// * `absl::StrAppendFormat()` to append a format string to a `string` +// * `absl::StreamFormat()` to more efficiently write a format string to a // stream, such as`std::cout`. // * `absl::PrintF()`, `absl::FPrintF()` and `absl::SNPrintF()` as // replacements for `std::printf()`, `std::fprintf()` and `std::snprintf()`. @@ -39,15 +39,15 @@ // Note: a version of `std::sprintf()` is not supported as it is // generally unsafe due to buffer overflows. // -// Additionally, you can provide a format std::string (and its associated arguments) +// Additionally, you can provide a format string (and its associated arguments) // using one of the following abstractions: // -// * A `FormatSpec` class template fully encapsulates a format std::string and its +// * A `FormatSpec` class template fully encapsulates a format string and its // type arguments and is usually provided to `str_format` functions as a // variadic argument of type `FormatSpec`. The `FormatSpec` // template is evaluated at compile-time, providing type safety. // * A `ParsedFormat` instance, which encapsulates a specific, pre-compiled -// format std::string for a specific set of type(s), and which can be passed +// format string for a specific set of type(s), and which can be passed // between API boundaries. (The `FormatSpec` type should not be used // directly.) // @@ -60,7 +60,7 @@ // // * A `FormatUntyped()` function that is similar to `Format()` except it is // loosely typed. `FormatUntyped()` is not a template and does not perform -// any compile-time checking of the format std::string; instead, it returns a +// any compile-time checking of the format string; instead, it returns a // boolean from a runtime check. // // In addition, the `str_format` library provides extension points for @@ -89,7 +89,7 @@ namespace absl { // Example: // // absl::UntypedFormatSpec format("%d"); -// std::string out; +// string out; // CHECK(absl::FormatUntyped(&out, format, {absl::FormatArg(1)})); class UntypedFormatSpec { public: @@ -135,7 +135,7 @@ str_format_internal::StreamedWrapper FormatStreamed(const T& v) { // Example: // // int n = 0; -// std::string s = absl::StrFormat("%s%d%n", "hello", 123, +// string s = absl::StrFormat("%s%d%n", "hello", 123, // absl::FormatCountCapture(&n)); // EXPECT_EQ(8, n); class FormatCountCapture { @@ -155,10 +155,10 @@ class FormatCountCapture { // FormatSpec // -// The `FormatSpec` type defines the makeup of a format std::string within the +// The `FormatSpec` type defines the makeup of a format string within the // `str_format` library. You should not need to use or manipulate this type // directly. A `FormatSpec` is a variadic class template that is evaluated at -// compile-time, according to the format std::string and arguments that are passed +// compile-time, according to the format string and arguments that are passed // to it. // // For a `FormatSpec` to be valid at compile-time, it must be provided as @@ -166,12 +166,12 @@ class FormatCountCapture { // // * A `constexpr` literal or `absl::string_view`, which is how it most often // used. -// * A `ParsedFormat` instantiation, which ensures the format std::string is +// * A `ParsedFormat` instantiation, which ensures the format string is // valid before use. (See below.) // // Example: // -// // Provided as a std::string literal. +// // Provided as a string literal. // absl::StrFormat("Welcome to %s, Number %d!", "The Village", 6); // // // Provided as a constexpr absl::string_view. @@ -183,7 +183,7 @@ class FormatCountCapture { // absl::ParsedFormat<'s', 'd'> formatString("Welcome to %s, Number %d!"); // absl::StrFormat(formatString, "TheVillage", 6); // -// A format std::string generally follows the POSIX syntax as used within the POSIX +// A format string generally follows the POSIX syntax as used within the POSIX // `printf` specification. // // (See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html.) @@ -223,7 +223,7 @@ class FormatCountCapture { // "%p", *int -> "0x7ffdeb6ad2a4" // // int n = 0; -// std::string s = absl::StrFormat( +// string s = absl::StrFormat( // "%s%d%n", "hello", 123, absl::FormatCountCapture(&n)); // EXPECT_EQ(8, n); // @@ -236,7 +236,7 @@ class FormatCountCapture { // // However, in the `str_format` library, a format conversion specifies a broader // C++ conceptual category instead of an exact type. For example, `%s` binds to -// any std::string-like argument, so `std::string`, `absl::string_view`, and +// any string-like argument, so `std::string`, `absl::string_view`, and // `const char*` are all accepted. Likewise, `%d` accepts any integer-like // argument, etc. @@ -248,7 +248,7 @@ using FormatSpec = // // A `ParsedFormat` is a class template representing a preparsed `FormatSpec`, // with template arguments specifying the conversion characters used within the -// format std::string. Such characters must be valid format type specifiers, and +// format string. Such characters must be valid format type specifiers, and // these type specifiers are checked at compile-time. // // Instances of `ParsedFormat` can be created, copied, and reused to speed up @@ -275,26 +275,26 @@ using ParsedFormat = str_format_internal::ExtendedParsedFormat< // StrFormat() // -// Returns a `string` given a `printf()`-style format std::string and zero or more +// Returns a `string` given a `printf()`-style format string and zero or more // additional arguments. Use it as you would `sprintf()`. `StrFormat()` is the // primary formatting function within the `str_format` library, and should be // used in most cases where you need type-safe conversion of types into // formatted strings. // -// The format std::string generally consists of ordinary character data along with +// The format string generally consists of ordinary character data along with // one or more format conversion specifiers (denoted by the `%` character). -// Ordinary character data is returned unchanged into the result std::string, while +// Ordinary character data is returned unchanged into the result string, while // each conversion specification performs a type substitution from // `StrFormat()`'s other arguments. See the comments for `FormatSpec` for full -// information on the makeup of this format std::string. +// information on the makeup of this format string. // // Example: // -// std::string s = absl::StrFormat( +// string s = absl::StrFormat( // "Welcome to %s, Number %d!", "The Village", 6); // EXPECT_EQ("Welcome to The Village, Number 6!", s); // -// Returns an empty std::string in case of error. +// Returns an empty string in case of error. template ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec& format, const Args&... args) { @@ -305,13 +305,13 @@ ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec& format, // StrAppendFormat() // -// Appends to a `dst` std::string given a format std::string, and zero or more additional +// Appends to a `dst` string given a format string, and zero or more additional // arguments, returning `*dst` as a convenience for chaining purposes. Appends // nothing in case of error (but possibly alters its capacity). // // Example: // -// std::string orig("For example PI is approximately "); +// string orig("For example PI is approximately "); // std::cout << StrAppendFormat(&orig, "%12.6f", 3.14); template std::string& StrAppendFormat(std::string* dst, const FormatSpec& format, @@ -323,7 +323,7 @@ std::string& StrAppendFormat(std::string* dst, const FormatSpec& format // StreamFormat() // -// Writes to an output stream given a format std::string and zero or more arguments, +// Writes to an output stream given a format string and zero or more arguments, // generally in a manner that is more efficient than streaming the result of // `absl:: StrFormat()`. The returned object must be streamed before the full // expression ends. @@ -341,7 +341,7 @@ ABSL_MUST_USE_RESULT str_format_internal::Streamable StreamFormat( // PrintF() // -// Writes to stdout given a format std::string and zero or more arguments. This +// Writes to stdout given a format string and zero or more arguments. This // function is functionally equivalent to `std::printf()` (and type-safe); // prefer `absl::PrintF()` over `std::printf()`. // @@ -361,7 +361,7 @@ int PrintF(const FormatSpec& format, const Args&... args) { // FPrintF() // -// Writes to a file given a format std::string and zero or more arguments. This +// Writes to a file given a format string and zero or more arguments. This // function is functionally equivalent to `std::fprintf()` (and type-safe); // prefer `absl::FPrintF()` over `std::fprintf()`. // @@ -382,7 +382,7 @@ int FPrintF(std::FILE* output, const FormatSpec& format, // SNPrintF() // -// Writes to a sized buffer given a format std::string and zero or more arguments. +// Writes to a sized buffer given a format string and zero or more arguments. // This function is functionally equivalent to `std::snprintf()` (and // type-safe); prefer `absl::SNPrintF()` over `std::snprintf()`. // @@ -430,14 +430,14 @@ class FormatRawSink { // Format() // -// Writes a formatted std::string to an arbitrary sink object (implementing the -// `absl::FormatRawSink` interface), using a format std::string and zero or more +// Writes a formatted string to an arbitrary sink object (implementing the +// `absl::FormatRawSink` interface), using a format string and zero or more // additional arguments. // // By default, `string` and `std::ostream` are supported as destination objects. // // `absl::Format()` is a generic version of `absl::StrFormat(), for custom -// sinks. The format std::string, like format strings for `StrFormat()`, is checked +// 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 @@ -463,13 +463,13 @@ using FormatArg = str_format_internal::FormatArgImpl; // FormatUntyped() // -// Writes a formatted std::string to an arbitrary sink object (implementing the +// Writes a formatted string to an arbitrary sink object (implementing the // `absl::FormatRawSink` interface), using an `UntypedFormatSpec` and zero or // more additional arguments. // // This function acts as the most generic formatting function in the // `str_format` library. The caller provides a raw sink, an unchecked format -// std::string, and (usually) a runtime specified list of arguments; no compile-time +// string, and (usually) a runtime specified list of arguments; no compile-time // checking of formatting is performed within this function. As a result, a // caller should check the return value to verify that no error occurred. // On failure, this function returns `false` and the state of the sink is @@ -483,9 +483,9 @@ using FormatArg = str_format_internal::FormatArgImpl; // // Example: // -// std::optional FormatDynamic(const std::string& in_format, -// const vector& in_args) { -// std::string out; +// std::optional FormatDynamic(const string& in_format, +// const vector& in_args) { +// string out; // std::vector args; // for (const auto& v : in_args) { // // It is important that 'v' is a reference to the objects in in_args. diff --git a/absl/strings/str_join.h b/absl/strings/str_join.h index b0680e83..f9611ad3 100644 --- a/absl/strings/str_join.h +++ b/absl/strings/str_join.h @@ -18,10 +18,10 @@ // ----------------------------------------------------------------------------- // // This header file contains functions for joining a range of elements and -// returning the result as a std::string. StrJoin operations are specified by passing -// a range, a separator std::string to use between the elements joined, and an +// returning the result as a string. StrJoin operations are specified by passing +// a range, a separator string to use between the elements joined, and an // optional Formatter responsible for converting each argument in the range to a -// std::string. If omitted, a default `AlphaNumFormatter()` is called on the elements +// string. If omitted, a default `AlphaNumFormatter()` is called on the elements // to be joined, using the same formatting that `absl::StrCat()` uses. This // package defines a number of default formatters, and you can define your own // implementations. @@ -29,7 +29,7 @@ // Ranges are specified by passing a container with `std::begin()` and // `std::end()` iterators, container-specific `begin()` and `end()` iterators, a // brace-initialized `std::initializer_list`, or a `std::tuple` of heterogeneous -// objects. The separator std::string is specified as an `absl::string_view`. +// objects. The separator string is specified as an `absl::string_view`. // // Because the default formatter uses the `absl::AlphaNum` class, // `absl::StrJoin()`, like `absl::StrCat()`, will work out-of-the-box on @@ -37,8 +37,8 @@ // // Example: // -// std::vector v = {"foo", "bar", "baz"}; -// std::string s = absl::StrJoin(v, "-"); +// std::vector v = {"foo", "bar", "baz"}; +// string s = absl::StrJoin(v, "-"); // EXPECT_EQ("foo-bar-baz", s); // // See comments on the `absl::StrJoin()` function for more examples. @@ -66,16 +66,16 @@ namespace absl { // ----------------------------------------------------------------------------- // // A Formatter is a function object that is responsible for formatting its -// argument as a std::string and appending it to a given output std::string. Formatters +// argument as a string and appending it to a given output string. Formatters // may be implemented as function objects, lambdas, or normal functions. You may // provide your own Formatter to enable `absl::StrJoin()` to work with arbitrary // types. // // The following is an example of a custom Formatter that simply uses -// `std::to_string()` to format an integer as a std::string. +// `std::to_string()` to format an integer as a string. // // struct MyFormatter { -// void operator()(std::string* out, int i) const { +// void operator()(string* out, int i) const { // out->append(std::to_string(i)); // } // }; @@ -84,7 +84,7 @@ namespace absl { // argument to `absl::StrJoin()`: // // std::vector v = {1, 2, 3, 4}; -// std::string s = absl::StrJoin(v, "-", MyFormatter()); +// string s = absl::StrJoin(v, "-", MyFormatter()); // EXPECT_EQ("1-2-3-4", s); // // The following standard formatters are provided within this file: @@ -156,10 +156,10 @@ DereferenceFormatter() { // StrJoin() // ----------------------------------------------------------------------------- // -// Joins a range of elements and returns the result as a std::string. -// `absl::StrJoin()` takes a range, a separator std::string to use between the +// Joins a range of elements and returns the result as a string. +// `absl::StrJoin()` takes a range, a separator string to use between the // elements joined, and an optional Formatter responsible for converting each -// argument in the range to a std::string. +// argument in the range to a string. // // If omitted, the default `AlphaNumFormatter()` is called on the elements to be // joined. @@ -167,22 +167,22 @@ DereferenceFormatter() { // Example 1: // // Joins a collection of strings. This pattern also works with a collection // // of `absl::string_view` or even `const char*`. -// std::vector v = {"foo", "bar", "baz"}; -// std::string s = absl::StrJoin(v, "-"); +// std::vector v = {"foo", "bar", "baz"}; +// string s = absl::StrJoin(v, "-"); // EXPECT_EQ("foo-bar-baz", s); // // Example 2: // // Joins the values in the given `std::initializer_list<>` specified using // // brace initialization. This pattern also works with an initializer_list // // of ints or `absl::string_view` -- any `AlphaNum`-compatible type. -// std::string s = absl::StrJoin({"foo", "bar", "baz"}, "-"); +// string s = absl::StrJoin({"foo", "bar", "baz"}, "-"); // EXPECT_EQ("foo-bar-baz", s); // // Example 3: // // Joins a collection of ints. This pattern also works with floats, // // doubles, int64s -- any `StrCat()`-compatible type. // std::vector v = {1, 2, 3, -4}; -// std::string s = absl::StrJoin(v, "-"); +// string s = absl::StrJoin(v, "-"); // EXPECT_EQ("1-2-3--4", s); // // Example 4: @@ -193,7 +193,7 @@ DereferenceFormatter() { // // `std::vector`. // int x = 1, y = 2, z = 3; // std::vector v = {&x, &y, &z}; -// std::string s = absl::StrJoin(v, "-"); +// string s = absl::StrJoin(v, "-"); // EXPECT_EQ("1-2-3", s); // // Example 5: @@ -202,42 +202,42 @@ DereferenceFormatter() { // v.emplace_back(new int(1)); // v.emplace_back(new int(2)); // v.emplace_back(new int(3)); -// std::string s = absl::StrJoin(v, "-"); +// string s = absl::StrJoin(v, "-"); // EXPECT_EQ("1-2-3", s); // // Example 6: // // Joins a `std::map`, with each key-value pair separated by an equals // // sign. This pattern would also work with, say, a // // `std::vector>`. -// std::map m = { +// std::map m = { // std::make_pair("a", 1), // std::make_pair("b", 2), // std::make_pair("c", 3)}; -// std::string s = absl::StrJoin(m, ",", absl::PairFormatter("=")); +// string s = absl::StrJoin(m, ",", absl::PairFormatter("=")); // EXPECT_EQ("a=1,b=2,c=3", s); // // Example 7: // // These examples show how `absl::StrJoin()` handles a few common edge // // cases: -// std::vector v_empty; +// std::vector v_empty; // EXPECT_EQ("", absl::StrJoin(v_empty, "-")); // -// std::vector v_one_item = {"foo"}; +// std::vector v_one_item = {"foo"}; // EXPECT_EQ("foo", absl::StrJoin(v_one_item, "-")); // -// std::vector v_empty_string = {""}; +// std::vector v_empty_string = {""}; // EXPECT_EQ("", absl::StrJoin(v_empty_string, "-")); // -// std::vector v_one_item_empty_string = {"a", ""}; +// std::vector v_one_item_empty_string = {"a", ""}; // EXPECT_EQ("a-", absl::StrJoin(v_one_item_empty_string, "-")); // -// std::vector v_two_empty_string = {"", ""}; +// std::vector v_two_empty_string = {"", ""}; // EXPECT_EQ("-", absl::StrJoin(v_two_empty_string, "-")); // // Example 8: // // Joins a `std::tuple` of heterogeneous types, converting each to -// // a std::string using the `absl::AlphaNum` class. -// std::string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-"); +// // a string using the `absl::AlphaNum` class. +// string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-"); // EXPECT_EQ("123-abc-0.456", s); template diff --git a/absl/strings/str_replace.h b/absl/strings/str_replace.h index f4d9bb95..b0f9d436 100644 --- a/absl/strings/str_replace.h +++ b/absl/strings/str_replace.h @@ -17,19 +17,19 @@ // File: str_replace.h // ----------------------------------------------------------------------------- // -// This file defines `absl::StrReplaceAll()`, a general-purpose std::string +// This file defines `absl::StrReplaceAll()`, a general-purpose string // replacement function designed for large, arbitrary text substitutions, // especially on strings which you are receiving from some other system for // further processing (e.g. processing regular expressions, escaping HTML // entities, etc. `StrReplaceAll` is designed to be efficient even when only // one substitution is being performed, or when substitution is rare. // -// If the std::string being modified is known at compile-time, and the substitutions +// If the string being modified is known at compile-time, and the substitutions // vary, `absl::Substitute()` may be a better choice. // // Example: // -// std::string html_escaped = absl::StrReplaceAll(user_input, { +// string html_escaped = absl::StrReplaceAll(user_input, { // {"&", "&"}, // {"<", "<"}, // {">", ">"}, @@ -49,16 +49,16 @@ namespace absl { // StrReplaceAll() // -// Replaces character sequences within a given std::string with replacements provided +// Replaces character sequences within a given string with replacements provided // within an initializer list of key/value pairs. Candidate replacements are -// considered in order as they occur within the std::string, with earlier matches +// considered in order as they occur within the string, with earlier matches // taking precedence, and longer matches taking precedence for candidates -// starting at the same position in the std::string. Once a substitution is made, the +// starting at the same position in the string. Once a substitution is made, the // replaced text is not considered for any further substitutions. // // Example: // -// std::string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!", +// string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!", // {{"$count", absl::StrCat(5)}, // {"$who", "Bob"}, // {"#Noun", "Apples"}}); @@ -78,28 +78,28 @@ ABSL_MUST_USE_RESULT std::string StrReplaceAll( // replacements["$who"] = "Bob"; // replacements["$count"] = "5"; // replacements["#Noun"] = "Apples"; -// std::string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!", +// string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!", // replacements); // EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s); // // // A std::vector of std::pair elements can be more efficient. -// std::vector> replacements; +// std::vector> replacements; // replacements.push_back({"&", "&"}); // replacements.push_back({"<", "<"}); // replacements.push_back({">", ">"}); -// std::string s = absl::StrReplaceAll("if (ptr < &foo)", +// string s = absl::StrReplaceAll("if (ptr < &foo)", // replacements); // EXPECT_EQ("if (ptr < &foo)", s); template std::string StrReplaceAll(absl::string_view s, const StrToStrMapping& replacements); // Overload of `StrReplaceAll()` to replace character sequences within a given -// output std::string *in place* with replacements provided within an initializer +// output string *in place* with replacements provided within an initializer // list of key/value pairs, returning the number of substitutions that occurred. // // Example: // -// std::string s = std::string("$who bought $count #Noun. Thanks $who!"); +// string s = std::string("$who bought $count #Noun. Thanks $who!"); // int count; // count = absl::StrReplaceAll({{"$count", absl::StrCat(5)}, // {"$who", "Bob"}, @@ -112,12 +112,12 @@ int StrReplaceAll( std::string* target); // Overload of `StrReplaceAll()` to replace patterns within a given output -// std::string *in place* with replacements provided within a container of key/value +// string *in place* with replacements provided within a container of key/value // pairs. // // Example: // -// std::string s = std::string("if (ptr < &foo)"); +// string s = std::string("if (ptr < &foo)"); // int count = absl::StrReplaceAll({{"&", "&"}, // {"<", "<"}, // {">", ">"}}, &s); diff --git a/absl/strings/str_replace_benchmark.cc b/absl/strings/str_replace_benchmark.cc index e608de8d..8386f2e6 100644 --- a/absl/strings/str_replace_benchmark.cc +++ b/absl/strings/str_replace_benchmark.cc @@ -38,16 +38,16 @@ struct Replacement { {"liquor", "shakes"}, // }; -// Here, we set up a std::string for use in global-replace benchmarks. +// Here, we set up a string for use in global-replace benchmarks. // We started with a million blanks, and then deterministically insert -// 10,000 copies each of two pangrams. The result is a std::string that is +// 10,000 copies each of two pangrams. The result is a string that is // 40% blank space and 60% these words. 'the' occurs 18,247 times and // all the substitutions together occur 49,004 times. // -// We then create "after_replacing_the" to be a std::string that is a result of +// We then create "after_replacing_the" to be a string that is a result of // replacing "the" with "box" in big_string. // -// And then we create "after_replacing_many" to be a std::string that is result +// And then we create "after_replacing_many" to be a string that is result // of preferring several substitutions. void SetUpStrings() { if (big_string == nullptr) { diff --git a/absl/strings/str_split.h b/absl/strings/str_split.h index 9a7be2b0..4cfba8d0 100644 --- a/absl/strings/str_split.h +++ b/absl/strings/str_split.h @@ -19,13 +19,13 @@ // // This file contains functions for splitting strings. It defines the main // `StrSplit()` function, several delimiters for determining the boundaries on -// which to split the std::string, and predicates for filtering delimited results. +// which to split the string, and predicates for filtering delimited results. // `StrSplit()` adapts the returned collection to the type specified by the // caller. // // Example: // -// // Splits the given std::string on commas. Returns the results in a +// // Splits the given string on commas. Returns the results in a // // vector of strings. // std::vector v = absl::StrSplit("a,b,c", ','); // // Can also use "," @@ -55,7 +55,7 @@ namespace absl { //------------------------------------------------------------------------------ // // `StrSplit()` uses delimiters to define the boundaries between elements in the -// provided input. Several `Delimiter` types are defined below. If a std::string +// provided input. Several `Delimiter` types are defined below. If a string // (`const char*`, `std::string`, or `absl::string_view`) is passed in place of // an explicit `Delimiter` object, `StrSplit()` treats it the same way as if it // were passed a `ByString` delimiter. @@ -65,7 +65,7 @@ namespace absl { // // The following `Delimiter` types are available for use within `StrSplit()`: // -// - `ByString` (default for std::string arguments) +// - `ByString` (default for string arguments) // - `ByChar` (default for a char argument) // - `ByAnyChar` // - `ByLength` @@ -76,15 +76,15 @@ namespace absl { // be split and the position to begin searching for the next delimiter in the // input text. The returned absl::string_view should refer to the next // occurrence (after pos) of the represented delimiter; this returned -// absl::string_view represents the next location where the input std::string should +// absl::string_view represents the next location where the input string should // be broken. The returned absl::string_view may be zero-length if the Delimiter -// does not represent a part of the std::string (e.g., a fixed-length delimiter). If +// does not represent a part of the string (e.g., a fixed-length delimiter). If // no delimiter is found in the given text, a zero-length absl::string_view // referring to text.end() should be returned (e.g., // absl::string_view(text.end(), 0)). It is important that the returned // absl::string_view always be within the bounds of input text given as an -// argument--it must not refer to a std::string that is physically located outside of -// the given std::string. +// argument--it must not refer to a string that is physically located outside of +// the given string. // // The following example is a simple Delimiter object that is created with a // single char and will look for that char in the text passed to the Find() @@ -104,13 +104,13 @@ namespace absl { // ByString // -// A sub-std::string delimiter. If `StrSplit()` is passed a std::string in place of a -// `Delimiter` object, the std::string will be implicitly converted into a +// A sub-string delimiter. If `StrSplit()` is passed a string in place of a +// `Delimiter` object, the string will be implicitly converted into a // `ByString` delimiter. // // Example: // -// // Because a std::string literal is converted to an `absl::ByString`, +// // Because a string literal is converted to an `absl::ByString`, // // the following two splits are equivalent. // // std::vector v1 = absl::StrSplit("a, b, c", ", "); @@ -131,7 +131,7 @@ class ByString { // ByChar // // A single character delimiter. `ByChar` is functionally equivalent to a -// 1-char std::string within a `ByString` delimiter, but slightly more +// 1-char string within a `ByString` delimiter, but slightly more // efficient. // // Example: @@ -164,9 +164,9 @@ class ByChar { // ByAnyChar // // A delimiter that will match any of the given byte-sized characters within -// its provided std::string. +// its provided string. // -// Note: this delimiter works with single-byte std::string data, but does not work +// Note: this delimiter works with single-byte string data, but does not work // with variable-width encodings, such as UTF-8. // // Example: @@ -175,8 +175,8 @@ class ByChar { // std::vector v = absl::StrSplit("a,b=c", ByAnyChar(",=")); // // v[0] == "a", v[1] == "b", v[2] == "c" // -// If `ByAnyChar` is given the empty std::string, it behaves exactly like -// `ByString` and matches each individual character in the input std::string. +// If `ByAnyChar` is given the empty string, it behaves exactly like +// `ByString` and matches each individual character in the input string. // class ByAnyChar { public: @@ -192,7 +192,7 @@ class ByAnyChar { // A delimiter for splitting into equal-length strings. The length argument to // the constructor must be greater than 0. // -// Note: this delimiter works with single-byte std::string data, but does not work +// Note: this delimiter works with single-byte string data, but does not work // with variable-width encodings, such as UTF-8. // // Example: @@ -202,7 +202,7 @@ class ByAnyChar { // // v[0] == "123", v[1] == "456", v[2] == "789" // -// Note that the std::string does not have to be a multiple of the fixed split +// Note that the string does not have to be a multiple of the fixed split // length. In such a case, the last substring will be shorter. // // using absl::ByLength; @@ -223,9 +223,9 @@ namespace strings_internal { // A traits-like metafunction for selecting the default Delimiter object type // for a particular Delimiter type. The base case simply exposes type Delimiter // itself as the delimiter's Type. However, there are specializations for -// std::string-like objects that map them to the ByString delimiter object. +// string-like objects that map them to the ByString delimiter object. // This allows functions like absl::StrSplit() and absl::MaxSplits() to accept -// std::string-like objects (e.g., ',') as delimiter arguments but they will be +// string-like objects (e.g., ',') as delimiter arguments but they will be // treated as if a ByString delimiter was given. template struct SelectDelimiter { @@ -331,7 +331,7 @@ struct AllowEmpty { // SkipEmpty() // // Returns `false` if the given `absl::string_view` is empty, indicating that -// `StrSplit()` should omit the empty std::string. +// `StrSplit()` should omit the empty string. // // Example: // @@ -339,7 +339,7 @@ struct AllowEmpty { // // // v[0] == "a", v[1] == "b" // -// Note: `SkipEmpty()` does not consider a std::string containing only whitespace +// Note: `SkipEmpty()` does not consider a string containing only whitespace // to be empty. To skip such whitespace as well, use the `SkipWhitespace()` // predicate. struct SkipEmpty { @@ -349,7 +349,7 @@ struct SkipEmpty { // SkipWhitespace() // // Returns `false` if the given `absl::string_view` is empty *or* contains only -// whitespace, indicating that `StrSplit()` should omit the std::string. +// whitespace, indicating that `StrSplit()` should omit the string. // // Example: // @@ -373,7 +373,7 @@ struct SkipWhitespace { // StrSplit() // -// Splits a given std::string based on the provided `Delimiter` object, returning the +// Splits a given string based on the provided `Delimiter` object, returning the // elements within the type specified by the caller. Optionally, you may pass a // `Predicate` to `StrSplit()` indicating whether to include or exclude the // resulting element within the final result set. (See the overviews for @@ -412,7 +412,7 @@ struct SkipWhitespace { // // The `StrSplit()` function adapts the returned collection to the collection // specified by the caller (e.g. `std::vector` above). The returned collections -// may contain `string`, `absl::string_view` (in which case the original std::string +// may contain `string`, `absl::string_view` (in which case the original string // being split must ensure that it outlives the collection), or any object that // can be explicitly created from an `absl::string_view`. This behavior works // for: @@ -424,7 +424,7 @@ struct SkipWhitespace { // Example: // // // The results are returned as `absl::string_view` objects. Note that we -// // have to ensure that the input std::string outlives any results. +// // have to ensure that the input string outlives any results. // std::vector v = absl::StrSplit("a,b,c", ','); // // // Stores results in a std::set, which also performs @@ -444,7 +444,7 @@ struct SkipWhitespace { // // is provided as a series of key/value pairs. For example, the 0th element // // resulting from the split will be stored as a key to the 1st element. If // // an odd number of elements are resolved, the last element is paired with -// // a default-constructed value (e.g., empty std::string). +// // a default-constructed value (e.g., empty string). // std::map m = absl::StrSplit("a,b,c", ','); // // m["a"] == "b", m["c"] == "" // last component value equals "" // @@ -452,14 +452,14 @@ struct SkipWhitespace { // elements and is not a collection type. When splitting to a `std::pair` the // first two split strings become the `std::pair` `.first` and `.second` // members, respectively. The remaining split substrings are discarded. If there -// are less than two split substrings, the empty std::string is used for the +// are less than two split substrings, the empty string is used for the // corresponding // `std::pair` member. // // Example: // // // Stores first two split strings as the members in a std::pair. -// std::pair p = absl::StrSplit("a,b,c", ','); +// std::pair p = absl::StrSplit("a,b,c", ','); // // p.first == "a", p.second == "b" // "c" is omitted. // // The `StrSplit()` function can be used multiple times to perform more @@ -467,9 +467,9 @@ struct SkipWhitespace { // // Example: // -// // The input std::string "a=b=c,d=e,f=,g" becomes +// // The input string "a=b=c,d=e,f=,g" becomes // // { "a" => "b=c", "d" => "e", "f" => "", "g" => "" } -// std::map m; +// std::map m; // for (absl::string_view sp : absl::StrSplit("a=b=c,d=e,f=,g", ',')) { // m.insert(absl::StrSplit(sp, absl::MaxSplits('=', 1))); // } diff --git a/absl/strings/str_split_test.cc b/absl/strings/str_split_test.cc index c6898863..557f72e9 100644 --- a/absl/strings/str_split_test.cc +++ b/absl/strings/str_split_test.cc @@ -276,7 +276,7 @@ TEST(SplitIterator, Basics) { EXPECT_EQ(it, end); } -// Simple Predicate to skip a particular std::string. +// Simple Predicate to skip a particular string. class Skip { public: explicit Skip(const std::string& s) : s_(s) {} @@ -768,7 +768,7 @@ static bool IsFoundAtStartingPos(absl::string_view text, Delimiter d, } // Helper function for testing Delimiter objects. Returns true if the given -// Delimiter is found in the given std::string at the given position. This function +// Delimiter is found in the given string at the given position. This function // tests two cases: // 1. The actual text given, staring at position 0 // 2. The text given with leading padding that should be ignored diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 96101463..9c03108b 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -19,7 +19,7 @@ // // This file contains the definition of the `absl::string_view` class. A // `string_view` points to a contiguous span of characters, often part or all of -// another `std::string`, double-quoted std::string literal, character array, or even +// another `std::string`, double-quoted string literal, character array, or even // another `string_view`. // // This `absl::string_view` abstraction is designed to be a drop-in @@ -56,15 +56,15 @@ namespace absl { // absl::string_view // -// A `string_view` provides a lightweight view into the std::string data provided by -// a `std::string`, double-quoted std::string literal, character array, or even -// another `string_view`. A `string_view` does *not* own the std::string to which it +// A `string_view` provides a lightweight view into the string data provided by +// a `std::string`, double-quoted string literal, character array, or even +// another `string_view`. A `string_view` does *not* own the string to which it // points, and that data cannot be modified through the view. // // You can use `string_view` as a function or method parameter anywhere a -// parameter can receive a double-quoted std::string literal, `const char*`, +// parameter can receive a double-quoted string literal, `const char*`, // `std::string`, or another `absl::string_view` argument with no need to copy -// the std::string data. Systematic use of `string_view` within function arguments +// the string data. Systematic use of `string_view` within function arguments // reduces data copies and `strlen()` calls. // // Because of its small size, prefer passing `string_view` by value: @@ -97,8 +97,8 @@ namespace absl { // `string_view` this way, it is your responsibility to ensure that the object // pointed to by the `string_view` outlives the `string_view`. // -// A `string_view` may represent a whole std::string or just part of a std::string. For -// example, when splitting a std::string, `std::vector` is a +// A `string_view` may represent a whole string or just part of a string. For +// example, when splitting a string, `std::vector` is a // natural data type for the output. // // diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc index 3818fb20..30d5f00b 100644 --- a/absl/strings/string_view_test.cc +++ b/absl/strings/string_view_test.cc @@ -284,7 +284,7 @@ TEST(StringViewTest, ComparisonOperatorsByCharacterPosition) { } #undef COMPARE -// Sadly, our users often confuse std::string::npos with absl::string_view::npos; +// Sadly, our users often confuse string::npos with absl::string_view::npos; // So much so that we test here that they are the same. They need to // both be unsigned, and both be the maximum-valued integer of their type. @@ -812,7 +812,7 @@ TEST(StringViewTest, FrontBackSingleChar) { } // `std::string_view::string_view(const char*)` calls -// `std::char_traits::length(const char*)` to get the std::string length. In +// `std::char_traits::length(const char*)` to get the string length. In // libc++, it doesn't allow `nullptr` in the constexpr context, with the error // "read of dereferenced null pointer is not allowed in a constant expression". // At run time, the behavior of `std::char_traits::length()` on `nullptr` is diff --git a/absl/strings/strip.h b/absl/strings/strip.h index 2f8d21f7..8d0d7c6b 100644 --- a/absl/strings/strip.h +++ b/absl/strings/strip.h @@ -17,7 +17,7 @@ // File: strip.h // ----------------------------------------------------------------------------- // -// This file contains various functions for stripping substrings from a std::string. +// This file contains various functions for stripping substrings from a string. #ifndef ABSL_STRINGS_STRIP_H_ #define ABSL_STRINGS_STRIP_H_ @@ -33,7 +33,7 @@ namespace absl { // ConsumePrefix() // -// Strips the `expected` prefix from the start of the given std::string, returning +// Strips the `expected` prefix from the start of the given string, returning // `true` if the strip operation succeeded or false otherwise. // // Example: @@ -48,7 +48,7 @@ inline bool ConsumePrefix(absl::string_view* str, absl::string_view expected) { } // ConsumeSuffix() // -// Strips the `expected` suffix from the end of the given std::string, returning +// Strips the `expected` suffix from the end of the given string, returning // `true` if the strip operation succeeded or false otherwise. // // Example: @@ -64,9 +64,9 @@ inline bool ConsumeSuffix(absl::string_view* str, absl::string_view expected) { // StripPrefix() // -// Returns a view into the input std::string 'str' with the given 'prefix' removed, -// but leaving the original std::string intact. If the prefix does not match at the -// start of the std::string, returns the original std::string instead. +// Returns a view into the input string 'str' with the given 'prefix' removed, +// but leaving the original string intact. If the prefix does not match at the +// start of the string, returns the original string instead. ABSL_MUST_USE_RESULT inline absl::string_view StripPrefix( absl::string_view str, absl::string_view prefix) { if (absl::StartsWith(str, prefix)) str.remove_prefix(prefix.size()); @@ -75,9 +75,9 @@ ABSL_MUST_USE_RESULT inline absl::string_view StripPrefix( // StripSuffix() // -// Returns a view into the input std::string 'str' with the given 'suffix' removed, -// but leaving the original std::string intact. If the suffix does not match at the -// end of the std::string, returns the original std::string instead. +// Returns a view into the input string 'str' with the given 'suffix' removed, +// but leaving the original string intact. If the suffix does not match at the +// end of the string, returns the original string instead. ABSL_MUST_USE_RESULT inline absl::string_view StripSuffix( absl::string_view str, absl::string_view suffix) { if (absl::EndsWith(str, suffix)) str.remove_suffix(suffix.size()); diff --git a/absl/strings/strip_test.cc b/absl/strings/strip_test.cc index 205c160c..40c4c607 100644 --- a/absl/strings/strip_test.cc +++ b/absl/strings/strip_test.cc @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// This file contains functions that remove a defined part from the std::string, -// i.e., strip the std::string. +// This file contains functions that remove a defined part from the string, +// i.e., strip the string. #include "absl/strings/strip.h" diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h index c4b25ba7..4de7b4e7 100644 --- a/absl/strings/substitute.h +++ b/absl/strings/substitute.h @@ -17,46 +17,46 @@ // File: substitute.h // ----------------------------------------------------------------------------- // -// This package contains functions for efficiently performing std::string -// substitutions using a format std::string with positional notation: +// This package contains functions for efficiently performing string +// substitutions using a format string with positional notation: // `Substitute()` and `SubstituteAndAppend()`. // // Unlike printf-style format specifiers, `Substitute()` functions do not need // to specify the type of the substitution arguments. Supported arguments -// following the format std::string, such as strings, string_views, ints, +// following the format string, such as strings, string_views, ints, // floats, and bools, are automatically converted to strings during the // substitution process. (See below for a full list of supported types.) // // `Substitute()` does not allow you to specify *how* to format a value, beyond -// the default conversion to std::string. For example, you cannot format an integer +// the default conversion to string. For example, you cannot format an integer // in hex. // -// The format std::string uses positional identifiers indicated by a dollar sign ($) +// The format string uses positional identifiers indicated by a dollar sign ($) // and single digit positional ids to indicate which substitution arguments to -// use at that location within the format std::string. +// use at that location within the format string. // // Example 1: -// std::string s = Substitute("$1 purchased $0 $2. Thanks $1!", +// string s = Substitute("$1 purchased $0 $2. Thanks $1!", // 5, "Bob", "Apples"); // EXPECT_EQ("Bob purchased 5 Apples. Thanks Bob!", s); // // Example 2: -// std::string s = "Hi. "; +// string s = "Hi. "; // SubstituteAndAppend(&s, "My name is $0 and I am $1 years old.", "Bob", 5); // EXPECT_EQ("Hi. My name is Bob and I am 5 years old.", s); // // // Supported types: -// * absl::string_view, std::string, const char* (null is equivalent to "") +// * absl::string_view, string, const char* (null is equivalent to "") // * int32_t, int64_t, uint32_t, uint64 // * float, double // * bool (Printed as "true" or "false") -// * pointer types other than char* (Printed as "0x", +// * pointer types other than char* (Printed as "0x", // except that null is printed as "NULL") // -// If an invalid format std::string is provided, Substitute returns an empty std::string -// and SubstituteAndAppend does not change the provided output std::string. -// A format std::string is invalid if it: +// If an invalid format string is provided, Substitute returns an empty string +// and SubstituteAndAppend does not change the provided output string. +// A format string is invalid if it: // * ends in an unescaped $ character, // e.g. "Hello $", or // * calls for a position argument which is not provided, @@ -88,7 +88,7 @@ namespace substitute_internal { // // This class provides an argument type for `absl::Substitute()` and // `absl::SubstituteAndAppend()`. `Arg` handles implicit conversion of various -// types to a std::string. (`Arg` is very similar to the `AlphaNum` class in +// types to a string. (`Arg` is very similar to the `AlphaNum` class in // `StrCat()`.) // // This class has implicit constructors. @@ -197,8 +197,8 @@ constexpr int PlaceholderBitmask(const char* format) { // SubstituteAndAppend() // -// Substitutes variables into a given format std::string and appends to a given -// output std::string. See file comments above for usage. +// Substitutes variables into a given format string and appends to a given +// output string. See file comments above for usage. // // The declarations of `SubstituteAndAppend()` below consist of overloads // for passing 0 to 10 arguments, respectively. @@ -444,7 +444,7 @@ void SubstituteAndAppend( // Substitute() // -// Substitutes variables into a given format std::string. See file comments above +// Substitutes variables into a given format string. See file comments above // for usage. // // The declarations of `Substitute()` below consist of overloads for passing 0 @@ -456,7 +456,7 @@ void SubstituteAndAppend( // Example: // template // void VarMsg(absl::string_view format, const Args&... args) { -// std::string s = absl::Substitute(format, args...); +// string s = absl::Substitute(format, args...); ABSL_MUST_USE_RESULT inline std::string Substitute(absl::string_view format) { std::string result; diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index e6525046..af1a5e4e 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc @@ -298,7 +298,7 @@ static struct SynchEvent { // this is a trivial hash table for the events // set "bits" in the word there (waiting until lockbit is clear before doing // so), and return a refcounted reference that will remain valid until // UnrefSynchEvent() is called. If a new SynchEvent is allocated, -// the std::string name is copied into it. +// the string name is copied into it. // When used with a mutex, the caller should also ensure that kMuEvent // is set in the mutex word, and similarly for condition variables and kCVEvent. static SynchEvent *EnsureSynchEvent(std::atomic *addr, @@ -1827,8 +1827,8 @@ bool Mutex::LockSlowWithDeadline(MuHow how, const Condition *cond, cond == nullptr || EvalConditionAnnotated(cond, this, true, how); } -// RAW_CHECK_FMT() takes a condition, a printf-style format std::string, and -// the printf-style argument list. The format std::string must be a literal. +// RAW_CHECK_FMT() takes a condition, a printf-style format string, and +// the printf-style argument list. The format string must be a literal. // Arguments after the first are not evaluated unless the condition is true. #define RAW_CHECK_FMT(cond, ...) \ do { \ diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 83c21486..a3781905 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -962,7 +962,7 @@ void RegisterMutexTracer(void (*fn)(const char *msg, const void *obj, // // The function pointer registered here will be called here on various CondVar // events. The callback is given an opaque handle to the CondVar object and -// a std::string identifying the event. This is thread-safe, but only a single +// a string identifying the event. This is thread-safe, but only a single // tracer can be registered. // // Events that can be sent are "Wait", "Unwait", "Signal wakeup", and diff --git a/absl/time/duration.cc b/absl/time/duration.cc index f402137b..2950c7cd 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc @@ -666,7 +666,7 @@ std::chrono::hours ToChronoHours(Duration d) { } // -// To/From std::string formatting. +// To/From string formatting. // namespace { @@ -744,7 +744,7 @@ void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) { } // namespace // From Go's doc at http://golang.org/pkg/time/#Duration.String -// [FormatDuration] returns a std::string representing the duration in the +// [FormatDuration] returns a string representing the duration in the // form "72h3m0.5s". Leading zero units are omitted. As a special // case, durations less than one second format use a smaller unit // (milli-, micro-, or nanoseconds) to ensure that the leading digit @@ -787,8 +787,8 @@ std::string FormatDuration(Duration d) { namespace { // A helper for ParseDuration() that parses a leading number from the given -// std::string and stores the result in *int_part/*frac_part/*frac_scale. The -// given std::string pointer is modified to point to the first unconsumed char. +// string and stores the result in *int_part/*frac_part/*frac_scale. The +// given string pointer is modified to point to the first unconsumed char. bool ConsumeDurationNumber(const char** dpp, int64_t* int_part, int64_t* frac_part, int64_t* frac_scale) { *int_part = 0; @@ -816,8 +816,8 @@ bool ConsumeDurationNumber(const char** dpp, int64_t* int_part, } // A helper for ParseDuration() that parses a leading unit designator (e.g., -// ns, us, ms, s, m, h) from the given std::string and stores the resulting unit -// in "*unit". The given std::string pointer is modified to point to the first +// ns, us, ms, s, m, h) from the given string and stores the resulting unit +// in "*unit". The given string pointer is modified to point to the first // unconsumed char. bool ConsumeDurationUnit(const char** start, Duration* unit) { const char *s = *start; @@ -850,7 +850,7 @@ bool ConsumeDurationUnit(const char** start, Duration* unit) { } // namespace // From Go's doc at http://golang.org/pkg/time/#ParseDuration -// [ParseDuration] parses a duration std::string. A duration std::string is +// [ParseDuration] parses a duration string. A duration string is // a possibly signed sequence of decimal numbers, each with optional // fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". // Valid time units are "ns", "us" "ms", "s", "m", "h". diff --git a/absl/time/format.cc b/absl/time/format.cc index e98e60a3..ee597e40 100644 --- a/absl/time/format.cc +++ b/absl/time/format.cc @@ -88,7 +88,7 @@ bool ParseTime(const std::string& format, const std::string& input, absl::Time* return absl::ParseTime(format, input, absl::UTCTimeZone(), time, err); } -// If the input std::string does not contain an explicit UTC offset, interpret +// If the input string does not contain an explicit UTC offset, interpret // the fields with respect to the given TimeZone. bool ParseTime(const std::string& format, const std::string& input, absl::TimeZone tz, absl::Time* time, std::string* err) { diff --git a/absl/time/internal/cctz/include/cctz/civil_time.h b/absl/time/internal/cctz/include/cctz/civil_time.h index 898222b4..0842fa4a 100644 --- a/absl/time/internal/cctz/include/cctz/civil_time.h +++ b/absl/time/internal/cctz/include/cctz/civil_time.h @@ -59,7 +59,7 @@ namespace cctz { // inferior fields to their minimum valid value (as described above). The // following are examples of how each of the six types would align the fields // representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the -// std::string format used here is not important; it's just a shorthand way of +// string format used here is not important; it's just a shorthand way of // showing the six YMDHMS fields.) // // civil_second 2015-11-22 12:34:56 diff --git a/absl/time/internal/cctz/include/cctz/time_zone.h b/absl/time/internal/cctz/include/cctz/time_zone.h index 0b9764ea..c86a5552 100644 --- a/absl/time/internal/cctz/include/cctz/time_zone.h +++ b/absl/time/internal/cctz/include/cctz/time_zone.h @@ -279,7 +279,7 @@ bool parse(const std::string&, const std::string&, const time_zone&, } // namespace detail // Formats the given time_point in the given cctz::time_zone according to -// the provided format std::string. Uses strftime()-like formatting options, +// the provided format string. Uses strftime()-like formatting options, // with the following extensions: // // - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm) @@ -298,7 +298,7 @@ bool parse(const std::string&, const std::string&, const time_zone&, // more than four characters, just like %Y. // // Tip: Format strings should include the UTC offset (e.g., %z, %Ez, or %E*z) -// so that the resulting std::string uniquely identifies an absolute time. +// so that the resulting string uniquely identifies an absolute time. // // Example: // cctz::time_zone lax; @@ -314,7 +314,7 @@ inline std::string format(const std::string& fmt, const time_point& tp, return detail::format(fmt, p.first, n, tz); } -// Parses an input std::string according to the provided format std::string and +// Parses an input string according to the provided format string and // returns the corresponding time_point. Uses strftime()-like formatting // options, with the same extensions as cctz::format(), but with the // exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez @@ -328,7 +328,7 @@ inline std::string format(const std::string& fmt, const time_point& tp, // // "1970-01-01 00:00:00.0 +0000" // -// For example, parsing a std::string of "15:45" (%H:%M) will return a time_point +// For example, parsing a string of "15:45" (%H:%M) will return a time_point // that represents "1970-01-01 15:45:00.0 +0000". // // Note that parse() returns time instants, so it makes most sense to parse diff --git a/absl/time/internal/cctz/src/time_zone_format.cc b/absl/time/internal/cctz/src/time_zone_format.cc index 1b023848..d9714092 100644 --- a/absl/time/internal/cctz/src/time_zone_format.cc +++ b/absl/time/internal/cctz/src/time_zone_format.cc @@ -533,7 +533,7 @@ const char* ParseSubSeconds(const char* dp, detail::femtoseconds* subseconds) { return dp; } -// Parses a std::string into a std::tm using strptime(3). +// Parses a string into a std::tm using strptime(3). const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) { if (dp != nullptr) { dp = strptime(dp, fmt, tm); diff --git a/absl/time/internal/cctz/src/time_zone_info.cc b/absl/time/internal/cctz/src/time_zone_info.cc index bf73635d..2cb358d0 100644 --- a/absl/time/internal/cctz/src/time_zone_info.cc +++ b/absl/time/internal/cctz/src/time_zone_info.cc @@ -286,7 +286,7 @@ bool TimeZoneInfo::EquivTransitions(std::uint_fast8_t tt1_index, return true; } -// Use the POSIX-TZ-environment-variable-style std::string to handle times +// Use the POSIX-TZ-environment-variable-style string to handle times // in years after the last transition stored in the zoneinfo data. void TimeZoneInfo::ExtendTransitions(const std::string& name, const Header& hdr) { diff --git a/absl/time/internal/cctz/src/time_zone_posix.h b/absl/time/internal/cctz/src/time_zone_posix.h index 6619f27e..9ccd4a8b 100644 --- a/absl/time/internal/cctz/src/time_zone_posix.h +++ b/absl/time/internal/cctz/src/time_zone_posix.h @@ -89,7 +89,7 @@ struct PosixTransition { } time; }; -// The entirety of a POSIX-std::string specified time-zone rule. The standard +// The entirety of a POSIX-string specified time-zone rule. The standard // abbreviation and offset are always given. If the time zone includes // daylight saving, then the daylight abbrevation is non-empty and the // remaining fields are also valid. Note that the start/end transitions diff --git a/absl/time/time.h b/absl/time/time.h index c41cb89c..d29d7e9a 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -481,7 +481,7 @@ std::chrono::hours ToChronoHours(Duration d); // FormatDuration() // -// Returns a std::string representing the duration in the form "72h3m0.5s". +// Returns a string representing the duration in the form "72h3m0.5s". // Returns "inf" or "-inf" for +/- `InfiniteDuration()`. std::string FormatDuration(Duration d); @@ -492,7 +492,7 @@ inline std::ostream& operator<<(std::ostream& os, Duration d) { // ParseDuration() // -// Parses a duration std::string consisting of a possibly signed sequence of +// Parses a duration string consisting of a possibly signed sequence of // decimal numbers, each with an optional fractional part and a unit // suffix. The valid suffixes are "ns", "us" "ms", "s", "m", and "h". // Simple examples include "300ms", "-1.5h", and "2h45m". Parses "0" as @@ -886,7 +886,7 @@ extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z // FormatTime() // // Formats the given `absl::Time` in the `absl::TimeZone` according to the -// provided format std::string. Uses strftime()-like formatting options, with +// provided format string. Uses strftime()-like formatting options, with // the following extensions: // // - %Ez - RFC3339-compatible numeric UTC offset (+hh:mm or -hh:mm) @@ -913,13 +913,13 @@ extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z // if (!absl::LoadTimeZone("America/Los_Angeles", &lax)) { ... } // absl::Time t = absl::FromDateTime(2013, 1, 2, 3, 4, 5, lax); // -// std::string f = absl::FormatTime("%H:%M:%S", t, lax); // "03:04:05" +// string f = absl::FormatTime("%H:%M:%S", t, lax); // "03:04:05" // f = absl::FormatTime("%H:%M:%E3S", t, lax); // "03:04:05.000" // // Note: If the given `absl::Time` is `absl::InfiniteFuture()`, the returned -// std::string will be exactly "infinite-future". If the given `absl::Time` is -// `absl::InfinitePast()`, the returned std::string will be exactly "infinite-past". -// In both cases the given format std::string and `absl::TimeZone` are ignored. +// string will be exactly "infinite-future". If the given `absl::Time` is +// `absl::InfinitePast()`, the returned string will be exactly "infinite-past". +// In both cases the given format string and `absl::TimeZone` are ignored. // std::string FormatTime(const std::string& format, Time t, TimeZone tz); @@ -936,7 +936,7 @@ inline std::ostream& operator<<(std::ostream& os, Time t) { // ParseTime() // -// Parses an input std::string according to the provided format std::string and +// Parses an input string according to the provided format string and // returns the corresponding `absl::Time`. Uses strftime()-like formatting // options, with the same extensions as FormatTime(), but with the // exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. %Ez @@ -950,7 +950,7 @@ inline std::ostream& operator<<(std::ostream& os, Time t) { // // "1970-01-01 00:00:00.0 +0000" // -// For example, parsing a std::string of "15:45" (%H:%M) will return an absl::Time +// For example, parsing a string of "15:45" (%H:%M) will return an absl::Time // that represents "1970-01-01 15:45:00.0 +0000". // // Note that since ParseTime() returns time instants, it makes the most sense @@ -977,15 +977,15 @@ inline std::ostream& operator<<(std::ostream& os, Time t) { // Errors are indicated by returning false and assigning an error message // to the "err" out param if it is non-null. // -// Note: If the input std::string is exactly "infinite-future", the returned +// Note: If the input string is exactly "infinite-future", the returned // `absl::Time` will be `absl::InfiniteFuture()` and `true` will be returned. -// If the input std::string is "infinite-past", the returned `absl::Time` will be +// If the input string is "infinite-past", the returned `absl::Time` will be // `absl::InfinitePast()` and `true` will be returned. // bool ParseTime(const std::string& format, const std::string& input, Time* time, std::string* err); -// Like ParseTime() above, but if the format std::string does not contain a UTC +// Like ParseTime() above, but if the format string does not contain a UTC // offset specification (%z/%Ez/%E*z) then the input is interpreted in the // given TimeZone. This means that the input, by itself, does not identify a // unique instant. Being time-zone dependent, it also admits the possibility diff --git a/absl/types/span.h b/absl/types/span.h index 76be819e..5387e8e0 100644 --- a/absl/types/span.h +++ b/absl/types/span.h @@ -87,7 +87,7 @@ constexpr auto GetDataImpl(C& c, char) noexcept // NOLINT(runtime/references) return c.data(); } -// Before C++17, std::string::data returns a const char* in all cases. +// Before C++17, string::data returns a const char* in all cases. inline char* GetDataImpl(std::string& s, // NOLINT(runtime/references) int) noexcept { return &s[0]; diff --git a/absl/utility/utility.h b/absl/utility/utility.h index d73602c4..aef4baa0 100644 --- a/absl/utility/utility.h +++ b/absl/utility/utility.h @@ -235,13 +235,13 @@ auto apply_helper(Functor&& functor, Tuple&& t, index_sequence) // Example: // // class Foo{void Bar(int);}; -// void user_function(int, std::string); +// void user_function(int, string); // void user_function(std::unique_ptr); // // int main() // { -// std::tuple tuple1(42, "bar"); -// // Invokes the user function overload on int, std::string. +// std::tuple tuple1(42, "bar"); +// // Invokes the user function overload on int, string. // absl::apply(&user_function, tuple1); // // auto foo = absl::make_unique(); -- cgit v1.2.3 From 0f4bc966754ec6cd28d5f03467d56f1efdc598e3 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 29 Aug 2018 15:09:00 -0700 Subject: Export of internal Abseil changes. -- ed4be0cb9a708158187a0628c1c2167ae6783274 by Greg Falcon : Refactor a string unit test into a template function for internal purposes. PiperOrigin-RevId: 210798880 -- e4c734be903ac7b3a88caf4b17909343c283a21a by Abseil Team : Add a note that the RFC3339_* format specifiers use %Y, and so do not produce 4-digit years on output nor require 4-digit years on input, as a strict reading of RFC3339 might require. PiperOrigin-RevId: 210785544 -- cfb5e32f9397e49ddb731445a191b36652fe2f6d by Greg Falcon : Refactor a string unit test into a template function for internal purposes. PiperOrigin-RevId: 210776525 -- 105ee700e62869cfda2a37e6f7c2ea483f8fc75e by Xiaoyi Zhang : Correctly define ABSL_HAVE_STD_STRING_VIEW for MSVC 2017. Currently the macro is not defined even though MSVC 2017 provides `std::string_view`, and this means both `absl::string_view` and `std::string_view` exist as distinct types. A bunch of places relying on the false assumption that `string_view::const_iterator` is `const char*` have to be fixed to build successfully. See related github issue https://github.com/abseil/abseil-cpp/issues/161. PiperOrigin-RevId: 210764947 GitOrigin-RevId: ed4be0cb9a708158187a0628c1c2167ae6783274 Change-Id: I7a9658b3201aa669db9d3d90474feb08072718c7 --- absl/base/config.h | 5 ++--- absl/strings/ascii.h | 4 ++-- absl/strings/escaping.cc | 2 +- absl/strings/internal/str_format/output.h | 4 ++-- absl/strings/internal/str_format/parser.cc | 4 ++-- absl/strings/internal/str_format/parser.h | 7 ++++--- absl/strings/internal/str_format/parser_test.cc | 4 ++-- absl/strings/internal/str_split_internal.h | 2 +- absl/strings/str_split.cc | 13 +++++++------ absl/strings/str_split.h | 3 ++- absl/strings/str_split_test.cc | 2 +- absl/strings/string_view_test.cc | 9 ++++++--- absl/time/time.h | 6 ++++-- 13 files changed, 36 insertions(+), 29 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index 035bd03f..d4eb7d0c 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -414,14 +414,13 @@ // , is implemented) or higher. Also, `__cplusplus` is // not correctly set by MSVC, so we use `_MSVC_LANG` to check the language // version. -// TODO(zhangxy): fix tests before enabling aliasing for `std::any`, -// `std::string_view`. +// TODO(zhangxy): fix tests before enabling aliasing for `std::any`. #if defined(_MSC_VER) && _MSC_VER >= 1910 && \ ((defined(_MSVC_LANG) && _MSVC_LANG > 201402) || __cplusplus > 201402) // #define ABSL_HAVE_STD_ANY 1 #define ABSL_HAVE_STD_OPTIONAL 1 #define ABSL_HAVE_STD_VARIANT 1 -// #define ABSL_HAVE_STD_STRING_VIEW 1 +#define ABSL_HAVE_STD_STRING_VIEW 1 #endif #endif // ABSL_BASE_CONFIG_H_ diff --git a/absl/strings/ascii.h b/absl/strings/ascii.h index 4195d093..48a9da22 100644 --- a/absl/strings/ascii.h +++ b/absl/strings/ascii.h @@ -195,7 +195,7 @@ ABSL_MUST_USE_RESULT inline std::string AsciiStrToUpper(absl::string_view s) { ABSL_MUST_USE_RESULT inline absl::string_view StripLeadingAsciiWhitespace( absl::string_view str) { auto it = std::find_if_not(str.begin(), str.end(), absl::ascii_isspace); - return absl::string_view(it, str.end() - it); + return str.substr(it - str.begin()); } // Strips in place whitespace from the beginning of the given string. @@ -209,7 +209,7 @@ inline void StripLeadingAsciiWhitespace(std::string* str) { ABSL_MUST_USE_RESULT inline absl::string_view StripTrailingAsciiWhitespace( absl::string_view str) { auto it = std::find_if_not(str.rbegin(), str.rend(), absl::ascii_isspace); - return absl::string_view(str.begin(), str.rend() - it); + return str.substr(0, str.rend() - it); } // Strips in place whitespace from the end of the given string diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc index 4a45942d..6742f446 100644 --- a/absl/strings/escaping.cc +++ b/absl/strings/escaping.cc @@ -104,7 +104,7 @@ bool CUnescapeInternal(absl::string_view source, bool leave_nulls_escaped, char* dest, ptrdiff_t* dest_len, std::string* error) { char* d = dest; const char* p = source.data(); - const char* end = source.end(); + const char* end = p + source.size(); const char* last_byte = end - 1; // Small optimization for case where source = dest and there's no escaping diff --git a/absl/strings/internal/str_format/output.h b/absl/strings/internal/str_format/output.h index 3b0aa5e7..12ecd99e 100644 --- a/absl/strings/internal/str_format/output.h +++ b/absl/strings/internal/str_format/output.h @@ -69,10 +69,10 @@ class FILERawSink { // Provide RawSink integration with common types from the STL. inline void AbslFormatFlush(std::string* out, string_view s) { - out->append(s.begin(), s.size()); + out->append(s.data(), s.size()); } inline void AbslFormatFlush(std::ostream* out, string_view s) { - out->write(s.begin(), s.size()); + out->write(s.data(), s.size()); } template bool ConsumeConversion(string_view *src, UnboundConversion *conv, int *next_arg) { - const char *pos = src->begin(); - const char *const end = src->end(); + const char *pos = src->data(); + const char *const end = pos + src->size(); char c; // Read the next char into `c` and update `pos`. Reads '\0' if at end. const auto get_char = [&] { c = pos == end ? '\0' : *pos++; }; diff --git a/absl/strings/internal/str_format/parser.h b/absl/strings/internal/str_format/parser.h index 7414e153..1022f062 100644 --- a/absl/strings/internal/str_format/parser.h +++ b/absl/strings/internal/str_format/parser.h @@ -90,7 +90,7 @@ bool ParseFormatString(string_view src, Consumer consumer) { int next_arg = 0; while (!src.empty()) { const char* percent = - static_cast(memchr(src.begin(), '%', src.size())); + static_cast(memchr(src.data(), '%', src.size())); if (!percent) { // We found the last substring. return consumer.Append(src); @@ -98,7 +98,7 @@ bool ParseFormatString(string_view src, Consumer consumer) { // We found a percent, so push the text run then process the percent. size_t percent_loc = percent - src.data(); if (!consumer.Append(string_view(src.data(), percent_loc))) return false; - if (percent + 1 >= src.end()) return false; + if (percent + 1 >= src.data() + src.size()) return false; UnboundConversion conv; @@ -178,7 +178,8 @@ class ParsedFormatBase { const char* const base = data_.get(); string_view text(base, 0); for (const auto& item : items_) { - text = string_view(text.end(), (base + item.text_end) - text.end()); + const char* const end = text.data() + text.size(); + text = string_view(end, (base + item.text_end) - end); if (item.is_conversion) { if (!consumer.ConvertOne(item.conv, text)) return false; } else { diff --git a/absl/strings/internal/str_format/parser_test.cc b/absl/strings/internal/str_format/parser_test.cc index e698020b..ac6886d0 100644 --- a/absl/strings/internal/str_format/parser_test.cc +++ b/absl/strings/internal/str_format/parser_test.cc @@ -66,10 +66,10 @@ class ConsumeUnboundConversionTest : public ::testing::Test { typedef UnboundConversion Props; string_view Consume(string_view* src) { int next = 0; - const char* prev_begin = src->begin(); + const char* prev_begin = src->data(); o = UnboundConversion(); // refresh ConsumeUnboundConversion(src, &o, &next); - return {prev_begin, static_cast(src->begin() - prev_begin)}; + return {prev_begin, static_cast(src->data() - prev_begin)}; } bool Run(const char *fmt, bool force_positional = false) { diff --git a/absl/strings/internal/str_split_internal.h b/absl/strings/internal/str_split_internal.h index 73a30fdf..81e8d555 100644 --- a/absl/strings/internal/str_split_internal.h +++ b/absl/strings/internal/str_split_internal.h @@ -159,7 +159,7 @@ class SplitIterator { } const absl::string_view text = splitter_->text(); const absl::string_view d = delimiter_.Find(text, pos_); - if (d.data() == text.end()) state_ = kLastState; + if (d.data() == text.data() + text.size()) state_ = kLastState; curr_ = text.substr(pos_, d.data() - (text.data() + pos_)); pos_ += curr_.size() + d.size(); } while (!predicate_(curr_)); diff --git a/absl/strings/str_split.cc b/absl/strings/str_split.cc index 0207213c..0a68c52d 100644 --- a/absl/strings/str_split.cc +++ b/absl/strings/str_split.cc @@ -43,10 +43,11 @@ absl::string_view GenericFind(absl::string_view text, if (delimiter.empty() && text.length() > 0) { // Special case for empty std::string delimiters: always return a zero-length // absl::string_view referring to the item at position 1 past pos. - return absl::string_view(text.begin() + pos + 1, 0); + return absl::string_view(text.data() + pos + 1, 0); } size_t found_pos = absl::string_view::npos; - absl::string_view found(text.end(), 0); // By default, not found + absl::string_view found(text.data() + text.size(), + 0); // By default, not found found_pos = find_policy.Find(text, delimiter, pos); if (found_pos != absl::string_view::npos) { found = absl::string_view(text.data() + found_pos, @@ -87,7 +88,7 @@ absl::string_view ByString::Find(absl::string_view text, size_t pos) const { // absl::string_view. size_t found_pos = text.find(delimiter_[0], pos); if (found_pos == absl::string_view::npos) - return absl::string_view(text.end(), 0); + return absl::string_view(text.data() + text.size(), 0); return text.substr(found_pos, 1); } return GenericFind(text, delimiter_, pos, LiteralPolicy()); @@ -100,7 +101,7 @@ absl::string_view ByString::Find(absl::string_view text, size_t pos) const { absl::string_view ByChar::Find(absl::string_view text, size_t pos) const { size_t found_pos = text.find(c_, pos); if (found_pos == absl::string_view::npos) - return absl::string_view(text.end(), 0); + return absl::string_view(text.data() + text.size(), 0); return text.substr(found_pos, 1); } @@ -128,9 +129,9 @@ absl::string_view ByLength::Find(absl::string_view text, // If the std::string is shorter than the chunk size we say we // "can't find the delimiter" so this will be the last chunk. if (substr.length() <= static_cast(length_)) - return absl::string_view(text.end(), 0); + return absl::string_view(text.data() + text.size(), 0); - return absl::string_view(substr.begin() + length_, 0); + return absl::string_view(substr.data() + length_, 0); } } // namespace absl diff --git a/absl/strings/str_split.h b/absl/strings/str_split.h index 4cfba8d0..c7eb280c 100644 --- a/absl/strings/str_split.h +++ b/absl/strings/str_split.h @@ -261,7 +261,8 @@ class MaxSplitsImpl { : delimiter_(delimiter), limit_(limit), count_(0) {} absl::string_view Find(absl::string_view text, size_t pos) { if (count_++ == limit_) { - return absl::string_view(text.end(), 0); // No more matches. + return absl::string_view(text.data() + text.size(), + 0); // No more matches. } return delimiter_.Find(text, pos); } diff --git a/absl/strings/str_split_test.cc b/absl/strings/str_split_test.cc index 557f72e9..caa88277 100644 --- a/absl/strings/str_split_test.cc +++ b/absl/strings/str_split_test.cc @@ -763,7 +763,7 @@ template static bool IsFoundAtStartingPos(absl::string_view text, Delimiter d, size_t starting_pos, int expected_pos) { absl::string_view found = d.Find(text, starting_pos); - return found.data() != text.end() && + return found.data() != text.data() + text.size() && expected_pos == found.data() - text.data(); } diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc index 30d5f00b..217fda04 100644 --- a/absl/strings/string_view_test.cc +++ b/absl/strings/string_view_test.cc @@ -816,11 +816,14 @@ TEST(StringViewTest, FrontBackSingleChar) { // libc++, it doesn't allow `nullptr` in the constexpr context, with the error // "read of dereferenced null pointer is not allowed in a constant expression". // At run time, the behavior of `std::char_traits::length()` on `nullptr` is -// undefined by the standard and usually results in crash with libc++. This -// conforms to the standard, but `absl::string_view` implements a different +// undefined by the standard and usually results in crash with libc++. +// In MSVC, creating a constexpr string_view from nullptr also triggers an +// "unevaluable pointer value" error. This compiler implementation conforms +// to the standard, but `absl::string_view` implements a different // behavior for historical reasons. We work around tests that construct // `string_view` from `nullptr` when using libc++. -#if !defined(ABSL_HAVE_STD_STRING_VIEW) || !defined(_LIBCPP_VERSION) +#if !defined(ABSL_HAVE_STD_STRING_VIEW) || \ + (!defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) #define ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 1 #endif // !defined(ABSL_HAVE_STD_STRING_VIEW) || !defined(_LIBCPP_VERSION) diff --git a/absl/time/time.h b/absl/time/time.h index 73977268..36e10b91 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -876,8 +876,10 @@ std::chrono::system_clock::time_point ToChronoTime(Time); // FormatTime()/ParseTime() format specifiers for RFC3339 date/time strings, // with trailing zeros trimmed or with fractional seconds omitted altogether. // -// Note that RFC3339_sec[] matches an ISO 8601 extended format for date -// and time with UTC offset. +// Note that RFC3339_sec[] matches an ISO 8601 extended format for date and +// time with UTC offset. Also note the use of "%Y": RFC3339 mandates that +// years have exactly four digits, but we allow them to take their natural +// width. extern const char RFC3339_full[]; // %Y-%m-%dT%H:%M:%E*S%Ez extern const char RFC3339_sec[]; // %Y-%m-%dT%H:%M:%S%Ez -- cgit v1.2.3 From 7b46e1d31a6b08b1c6da2a13e7b151a20446fa07 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 13 Nov 2018 13:22:00 -0800 Subject: Export of internal Abseil changes. -- 07575526242a8e1275ac4223a3d2822795f46569 by CJ Johnson : Comment cleanup on InlinedVector PiperOrigin-RevId: 221322176 -- 49a5e643f85e34d53c41f5e6cc33357c55c9115d by Matt Kulukundis : Internal cleanup PiperOrigin-RevId: 221309185 -- bb35be87ec9c74244b7d902e7e7d2d33ab139d76 by Abseil Team : Fix typo in comment. PiperOrigin-RevId: 221145354 -- afd4d7c106919708004e06aeea068a57c28aec44 by Derek Mauro : Update the debugging log message in CallOnceImpl() PiperOrigin-RevId: 221103254 -- 0b9dace8b88113777bf26a6d38f9bc0bcaf053a1 by Abseil Team : Workaround an MSVC 2015 bug in compile-time initialization. PiperOrigin-RevId: 220871483 -- ea0a3854511ed26beab827e5a5113766b334db86 by Marek Gilbert : Fix ABSL_HAVE_THREAD_LOCAL when compiling for iOS 8 with Xcode 10. Xcode 10 has moved the check for thread_local to a link time, so clang reports __has_feature(cxx_thread_local) but then linking fails with messages like this: ld: targeted OS version does not support use of thread local variables PiperOrigin-RevId: 220815885 -- 485b6876c158c3dcf37eb32d7e512242d5d4ecc6 by Greg Falcon : Make the absl::c_set_xxxx() algorithms refuse to compile when passed an unordered collection from std:: or absl::. These algorithms operate on sorted sequences; passing an unordered container to them is nearly certainly a bug. This change is technically an API break, but it only breaks incorrect code. We could try to be more clever and detect unordered collections from other libraries, but false positives will break legal code, and this would constitute an API break Abseil cannot afford. PiperOrigin-RevId: 220794190 -- c47cff7f9cc70a4c1604eee0131af552f40e46d6 by Jon Cohen : MSVC 2017's STL throws a Structured Exception (not a C++ exception, essentially equivalent to SIGSEGV) when variant::emplace calls a throwing constructor when using the debug multithreaded MSVC runtime DLL. This manifests in dbg mode in Bazel builds. Disable tests which trigger this bug. It's impossible to specifically pull out MSVC 2017 -dbg modes because there's no way for Bazel to know when version of MSVC is being used -- you tell Bazel the directory where the MSVC tools live, not which version of MSVC tools to use. Thus the best we can do is switch on _DEBUG, which is set whenever the debug runtime is selected with the /MDd build flag, as in Bazel -dbg modes. See https://msdn.microsoft.com/en-us/library/b0084kay.aspx ctrl-f "_DEBUG" PiperOrigin-RevId: 220706161 -- 43993d4af309d92f4ebff38391dcc245f154ecc7 by Shaindel Schwartz : Internal change PiperOrigin-RevId: 220688429 -- 2448802972dcc261af153af464f2b022ef54a2a9 by Abseil Team : Speed up operator* for uint128 in WIN64. PiperOrigin-RevId: 220678790 -- 7b376403dd05ba10152fb52e40b29d8af79b58bb by Abseil Team : Import of CCTZ from GitHub. PiperOrigin-RevId: 220654834 -- ae08af58111c3f838b8d4de25f501c3559c86002 by Abseil Team : CMake: Add absl_cc_test function PiperOrigin-RevId: 220603940 GitOrigin-RevId: 07575526242a8e1275ac4223a3d2822795f46569 Change-Id: Iba7f53eb394c8a9de564582a976793f9bb0596d9 --- CMake/AbseilHelpers.cmake | 83 ++++++++- absl/algorithm/container.h | 78 +++++++- absl/base/call_once.h | 8 +- absl/base/config.h | 24 ++- absl/container/BUILD.bazel | 4 + absl/container/flat_hash_map.h | 12 ++ absl/container/flat_hash_set.h | 12 ++ absl/container/inlined_vector.h | 41 +++-- absl/container/internal/hash_generator_testing.cc | 8 +- absl/container/internal/hash_generator_testing.h | 8 +- absl/container/node_hash_map.h | 14 +- absl/container/node_hash_set.h | 11 ++ absl/numeric/int128.h | 11 ++ absl/synchronization/lifetime_test.cc | 15 +- absl/synchronization/notification.cc | 1 + absl/time/duration_test.cc | 11 ++ absl/time/internal/cctz/src/time_zone_libc.cc | 200 +++++++++++++++++---- .../internal/cctz/src/time_zone_lookup_test.cc | 100 ++++++++++- absl/time/time.h | 18 +- absl/types/BUILD.bazel | 1 + absl/types/variant_exception_safety_test.cc | 6 + absl/types/variant_test.cc | 9 +- 22 files changed, 564 insertions(+), 111 deletions(-) (limited to 'absl/base/config.h') diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake index d4870365..3b9148ea 100644 --- a/CMake/AbseilHelpers.cmake +++ b/CMake/AbseilHelpers.cmake @@ -62,7 +62,6 @@ function(absl_library) endif() endfunction() -# # CMake function to imitate Bazel's cc_library rule. # # Parameters: @@ -77,14 +76,13 @@ endfunction() # TESTONLY: When added, this target will only be built if user passes -DABSL_RUN_TESTS=ON to CMake. # # Note: -# # By default, absl_cc_library will always create a library named absl_internal_${NAME}, # which means other targets can only depend this library as absl_internal_${NAME}, not ${NAME}. # This is to reduce namespace pollution. # # absl_cc_library( # NAME -# awesome_lib +# awesome # HDRS # "a.h" # SRCS @@ -96,7 +94,7 @@ endfunction() # SRCS # "b.cc" # DEPS -# absl_internal_awesome_lib # not "awesome_lib"! +# absl_internal_awesome # not "awesome"! # ) # # If PUBLIC is set, absl_cc_library will instead create a target named @@ -112,7 +110,6 @@ endfunction() # User can then use the library as absl::main_lib (although absl_main_lib is defined too). # # TODO: Implement "ALWAYSLINK" - function(absl_cc_library) cmake_parse_arguments(ABSL_CC_LIB "DISABLE_INSTALL;PUBLIC;TESTONLY" @@ -153,7 +150,8 @@ function(absl_cc_library) else() # Generating header-only library add_library(${_NAME} INTERFACE) - target_include_directories(${_NAME} INTERFACE ${ABSL_COMMON_INCLUDE_DIRS}) + target_include_directories(${_NAME} + INTERFACE ${ABSL_COMMON_INCLUDE_DIRS}) target_link_libraries(${_NAME} INTERFACE ${ABSL_CC_LIB_DEPS} ${ABSL_CC_LIB_LINKOPTS} ) @@ -166,6 +164,78 @@ function(absl_cc_library) endif() endfunction() +# absl_cc_test() +# +# CMake function to imitate Bazel's cc_test rule. +# +# Parameters: +# NAME: name of target (see Usage below) +# SRCS: List of source files for the binary +# DEPS: List of other libraries to be linked in to the binary targets +# COPTS: List of private compile options +# DEFINES: List of public defines +# LINKOPTS: List of link options +# +# Note: +# By default, absl_cc_test will always create a binary named absl_${NAME}. +# This will also add it to ctest list as absl_${NAME}. +# +# Usage: +# absl_cc_library( +# NAME +# awesome +# HDRS +# "a.h" +# SRCS +# "a.cc" +# PUBLIC +# ) +# +# absl_cc_test( +# NAME +# awesome_test +# SRCS +# "awesome_test.cc" +# DEPS +# absl::awesome +# gmock +# gtest_main +# ) +function(absl_cc_test) + if(NOT ABSL_RUN_TESTS) + return() + endif() + + cmake_parse_arguments(ABSL_CC_TEST + "" + "NAME" + "SRCS;COPTS;DEFINES;LINKOPTS;DEPS" + ${ARGN} + ) + + set(_NAME "absl_${ABSL_CC_TEST_NAME}") + add_executable(${_NAME} "") + target_sources(${_NAME} PRIVATE ${ABSL_CC_TEST_SRCS}) + target_include_directories(${_NAME} + PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} + PRIVATE ${GMOCK_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS} + ) + target_compile_definitions(${_NAME} + PUBLIC ${ABSL_CC_TEST_DEFINES} + ) + target_compile_options(${_NAME} + PRIVATE ${ABSL_CC_TEST_COPTS} + ) + target_link_libraries(${_NAME} + PUBLIC ${ABSL_CC_TEST_DEPS} + PRIVATE ${ABSL_CC_TEST_LINKOPTS} + ) + # Add all Abseil targets to a a folder in the IDE for organization. + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) + + add_test(NAME ${_NAME} COMMAND ${_NAME}) +endfunction() + # # header only virtual target creation # @@ -211,7 +281,6 @@ function(absl_header_library) endfunction() - # # create an abseil unit_test and add it to the executed test list # diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h index 53ab1568..6d5f6630 100644 --- a/absl/algorithm/container.h +++ b/absl/algorithm/container.h @@ -46,6 +46,8 @@ #include #include #include +#include +#include #include #include @@ -54,7 +56,6 @@ #include "absl/meta/type_traits.h" namespace absl { - namespace container_algorithm_internal { // NOTE: it is important to defer to ADL lookup for building with C++ modules, @@ -101,6 +102,17 @@ ContainerIter c_begin(C& c) { return begin(c); } template ContainerIter c_end(C& c) { return end(c); } +template +struct IsUnorderedContainer : std::false_type {}; + +template +struct IsUnorderedContainer< + std::unordered_map> : std::true_type {}; + +template +struct IsUnorderedContainer> + : std::true_type {}; + } // namespace container_algorithm_internal // PUBLIC API @@ -1154,7 +1166,13 @@ bool c_includes(const C1& c1, const C2& c2, Compare&& comp) { // Container-based version of the `std::set_union()` function // to return an iterator containing the union of two containers; duplicate // values are not copied into the output. -template +template ::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer::value, + void>::type> OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output) { return std::set_union(container_algorithm_internal::c_begin(c1), container_algorithm_internal::c_end(c1), @@ -1164,7 +1182,13 @@ OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output) { // Overload of c_set_union() for performing a merge using a `comp` other than // `operator<`. -template +template ::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer::value, + void>::type> OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output, Compare&& comp) { return std::set_union(container_algorithm_internal::c_begin(c1), @@ -1178,7 +1202,13 @@ OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output, // // Container-based version of the `std::set_intersection()` function // to return an iterator containing the intersection of two containers. -template +template ::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer::value, + void>::type> OutputIterator c_set_intersection(const C1& c1, const C2& c2, OutputIterator output) { return std::set_intersection(container_algorithm_internal::c_begin(c1), @@ -1189,7 +1219,13 @@ OutputIterator c_set_intersection(const C1& c1, const C2& c2, // Overload of c_set_intersection() for performing a merge using a `comp` other // than `operator<`. -template +template ::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer::value, + void>::type> OutputIterator c_set_intersection(const C1& c1, const C2& c2, OutputIterator output, Compare&& comp) { return std::set_intersection(container_algorithm_internal::c_begin(c1), @@ -1204,7 +1240,13 @@ OutputIterator c_set_intersection(const C1& c1, const C2& c2, // Container-based version of the `std::set_difference()` function // to return an iterator containing elements present in the first container but // not in the second. -template +template ::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer::value, + void>::type> OutputIterator c_set_difference(const C1& c1, const C2& c2, OutputIterator output) { return std::set_difference(container_algorithm_internal::c_begin(c1), @@ -1215,7 +1257,13 @@ OutputIterator c_set_difference(const C1& c1, const C2& c2, // Overload of c_set_difference() for performing a merge using a `comp` other // than `operator<`. -template +template ::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer::value, + void>::type> OutputIterator c_set_difference(const C1& c1, const C2& c2, OutputIterator output, Compare&& comp) { return std::set_difference(container_algorithm_internal::c_begin(c1), @@ -1230,7 +1278,13 @@ OutputIterator c_set_difference(const C1& c1, const C2& c2, // Container-based version of the `std::set_symmetric_difference()` // function to return an iterator containing elements present in either one // container or the other, but not both. -template +template ::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer::value, + void>::type> OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, OutputIterator output) { return std::set_symmetric_difference( @@ -1242,7 +1296,13 @@ OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, // Overload of c_set_symmetric_difference() for performing a merge using a // `comp` other than `operator<`. -template +template ::value, + void>::type, + typename = typename std::enable_if< + !container_algorithm_internal::IsUnorderedContainer::value, + void>::type> OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, OutputIterator output, Compare&& comp) { diff --git a/absl/base/call_once.h b/absl/base/call_once.h index 532ee2e3..f6c8ebb2 100644 --- a/absl/base/call_once.h +++ b/absl/base/call_once.h @@ -150,12 +150,8 @@ void CallOnceImpl(std::atomic* control, old_control != kOnceRunning && old_control != kOnceWaiter && old_control != kOnceDone) { - ABSL_RAW_LOG( - FATAL, - "Unexpected value for control word: %lx. Either the control word " - "has non-static storage duration (where GoogleOnceDynamic might " - "be appropriate), or there's been a memory corruption.", - static_cast(old_control)); // NOLINT + ABSL_RAW_LOG(FATAL, "Unexpected value for control word: 0x%lx", + static_cast(old_control)); // NOLINT } } #endif // NDEBUG diff --git a/absl/base/config.h b/absl/base/config.h index d4eb7d0c..e3edb2bf 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -139,12 +139,18 @@ #ifdef ABSL_HAVE_THREAD_LOCAL #error ABSL_HAVE_THREAD_LOCAL cannot be directly set #elif defined(__APPLE__) -// Notes: Xcode's clang did not support `thread_local` until version -// 8, and even then not for all iOS < 9.0. Also, Xcode 9.3 started disallowing -// `thread_local` for 32-bit iOS simulator targeting iOS 9.x. -// `__has_feature` is only supported by Clang so it has be inside +// Notes: +// * Xcode's clang did not support `thread_local` until version 8, and +// even then not for all iOS < 9.0. +// * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator +// targeting iOS 9.x. +// * Xcode 10 moves the deployment target check for iOS < 9.0 to link time +// making __has_feature unreliable there. +// +// Otherwise, `__has_feature` is only supported by Clang so it has be inside // `defined(__APPLE__)` check. -#if __has_feature(cxx_thread_local) +#if __has_feature(cxx_thread_local) && \ + !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0) #define ABSL_HAVE_THREAD_LOCAL 1 #endif #else // !defined(__APPLE__) @@ -423,4 +429,12 @@ #define ABSL_HAVE_STD_STRING_VIEW 1 #endif +// In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION +// SEH exception from emplace for variant when constructing the +// struct can throw. This defeats some of variant_test and +// variant_exception_safety_test. +#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_DEBUG) +#define ABSL_INTERNAL_MSVC_2017_DBG_MODE +#endif + #endif // ABSL_BASE_CONFIG_H_ diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index d75f8916..afc869f4 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -212,6 +212,7 @@ cc_library( ":container_memory", ":hash_function_defaults", ":raw_hash_map", + "//absl/algorithm:container", "//absl/memory", ], ) @@ -240,6 +241,7 @@ cc_library( ":container_memory", ":hash_function_defaults", ":raw_hash_set", + "//absl/algorithm:container", "//absl/base:core_headers", "//absl/memory", ], @@ -271,6 +273,7 @@ cc_library( ":hash_function_defaults", ":node_hash_policy", ":raw_hash_map", + "//absl/algorithm:container", "//absl/memory", ], ) @@ -299,6 +302,7 @@ cc_library( ":hash_function_defaults", ":node_hash_policy", ":raw_hash_set", + "//absl/algorithm:container", "//absl/memory", ], ) diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h index de632be2..7bc21380 100644 --- a/absl/container/flat_hash_map.h +++ b/absl/container/flat_hash_map.h @@ -35,6 +35,7 @@ #include #include +#include "absl/algorithm/container.h" #include "absl/container/internal/container_memory.h" #include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/raw_hash_map.h" // IWYU pragma: export @@ -564,5 +565,16 @@ struct FlatHashMapPolicy { }; } // namespace container_internal + +namespace container_algorithm_internal { + +// Specialization of trait in absl/algorithm/container.h +template +struct IsUnorderedContainer< + absl::flat_hash_map> : std::true_type {}; + +} // namespace container_algorithm_internal + } // namespace absl + #endif // ABSL_CONTAINER_FLAT_HASH_MAP_H_ diff --git a/absl/container/flat_hash_set.h b/absl/container/flat_hash_set.h index a2584d66..f7c1acaa 100644 --- a/absl/container/flat_hash_set.h +++ b/absl/container/flat_hash_set.h @@ -32,6 +32,7 @@ #include #include +#include "absl/algorithm/container.h" #include "absl/base/macros.h" #include "absl/container/internal/container_memory.h" #include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export @@ -475,5 +476,16 @@ struct FlatHashSetPolicy { static size_t space_used(const T*) { return 0; } }; } // namespace container_internal + +namespace container_algorithm_internal { + +// Specialization of trait in absl/algorithm/container.h +template +struct IsUnorderedContainer> + : std::true_type {}; + +} // namespace container_algorithm_internal + } // namespace absl + #endif // ABSL_CONTAINER_FLAT_HASH_SET_H_ diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index ea8cb02b..642dae6c 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -20,17 +20,17 @@ // vector" which behaves in an equivalent fashion to a `std::vector`, except // that storage for small sequences of the vector are provided inline without // requiring any heap allocation. - -// An `absl::InlinedVector` specifies the size N at which to inline as one -// of its template parameters. Vectors of length <= N are provided inline. -// Typically N is very small (e.g., 4) so that sequences that are expected to be -// short do not require allocations. - -// An `absl::InlinedVector` does not usually require a specific allocator; if +// +// An `absl::InlinedVector` specifies the default capacity `N` as one of +// its template parameters. Instances where `size() <= N` hold contained +// elements in inline space. Typically `N` is very small so that sequences that +// are expected to be short do not require allocations. +// +// An `absl::InlinedVector` does not usually require a specific allocator. If // the inlined vector grows beyond its initial constraints, it will need to -// allocate (as any normal `std::vector` would) and it will generally use the -// default allocator in that case; optionally, a custom allocator may be -// specified using an `absl::InlinedVector` construction. +// allocate (as any normal `std::vector` would). This is usually performed with +// the default allocator (defined as `std::allocator`). Optionally, a custom +// allocator type may be specified as `A` in `absl::InlinedVector`. #ifndef ABSL_CONTAINER_INLINED_VECTOR_H_ #define ABSL_CONTAINER_INLINED_VECTOR_H_ @@ -61,8 +61,8 @@ namespace absl { // An `absl::InlinedVector` is designed to be a drop-in replacement for // `std::vector` for use cases where the vector's size is sufficiently small // that it can be inlined. If the inlined vector does grow beyond its estimated -// size, it will trigger an initial allocation on the heap, and will behave as a -// `std:vector`. The API of the `absl::InlinedVector` within this file is +// capacity, it will trigger an initial allocation on the heap, and will behave +// as a `std:vector`. The API of the `absl::InlinedVector` within this file is // designed to cover the same API footprint as covered by `std::vector`. template > class InlinedVector { @@ -101,7 +101,6 @@ class InlinedVector { using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - // --------------------------------------------------------------------------- // InlinedVector Constructors and Destructor // --------------------------------------------------------------------------- @@ -135,11 +134,12 @@ class InlinedVector { AppendRange(init_list.begin(), init_list.end()); } - // Creates and initialize with the elements [`first`, `last`). + // Creates an inlined vector with elements constructed from the provided + // Iterator range [`first`, `last`). // // NOTE: The `enable_if` prevents ambiguous interpretation between a call to - // this constructor with two integral arguments and a call to the preceding - // `InlinedVector(n, v)` constructor. + // this constructor with two integral arguments and a call to the above + // `InlinedVector(size_type, const_reference)` constructor. template * = nullptr> InlinedVector(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) @@ -153,11 +153,11 @@ class InlinedVector { // Creates a copy of `other` but with a specified allocator. InlinedVector(const InlinedVector& other, const allocator_type& alloc); - // Creates an inlined vector with the contents of `other`. + // Creates an inlined vector by moving in the contents of `other`. // // NOTE: This move constructor does not allocate and only moves the underlying // objects, so its `noexcept` specification depends on whether moving the - // underlying objects can throw or not. We assume + // underlying objects can throw or not. We assume: // a) move constructors should only throw due to allocation failure and // b) if `value_type`'s move constructor allocates, it uses the same // allocation function as the `InlinedVector`'s allocator, so the move @@ -167,9 +167,9 @@ class InlinedVector { absl::allocator_is_nothrow::value || std::is_nothrow_move_constructible::value); - // Creates an inlined vector with the contents of `other`. + // Creates an inlined vector by moving in the contents of `other`. // - // NOTE: This move constructor allocates and also moves the underlying + // NOTE: This move constructor allocates and subsequently moves the underlying // objects, so its `noexcept` specification depends on whether the allocation // can throw and whether moving the underlying objects can throw. Based on the // same assumptions as above, the `noexcept` specification is dominated by @@ -180,7 +180,6 @@ class InlinedVector { ~InlinedVector() { clear(); } - // --------------------------------------------------------------------------- // InlinedVector Member Accessors // --------------------------------------------------------------------------- diff --git a/absl/container/internal/hash_generator_testing.cc b/absl/container/internal/hash_generator_testing.cc index 0d6a9df1..e0fefbff 100644 --- a/absl/container/internal/hash_generator_testing.cc +++ b/absl/container/internal/hash_generator_testing.cc @@ -39,9 +39,9 @@ class RandomDeviceSeedSeq { } // namespace -std::mt19937_64* GetThreadLocalRng() { +std::mt19937_64* GetSharedRng() { RandomDeviceSeedSeq seed_seq; - thread_local auto* rng = new std::mt19937_64(seed_seq); + static auto* rng = new std::mt19937_64(seed_seq); return rng; } @@ -51,7 +51,7 @@ std::string Generator::operator()() const { std::string res; res.resize(32); std::generate(res.begin(), res.end(), - [&]() { return chars(*GetThreadLocalRng()); }); + [&]() { return chars(*GetSharedRng()); }); return res; } @@ -63,7 +63,7 @@ absl::string_view Generator::operator()() const { auto& res = arena->back(); res.resize(32); std::generate(res.begin(), res.end(), - [&]() { return chars(*GetThreadLocalRng()); }); + [&]() { return chars(*GetSharedRng()); }); return res; } diff --git a/absl/container/internal/hash_generator_testing.h b/absl/container/internal/hash_generator_testing.h index 50d77102..6521efe8 100644 --- a/absl/container/internal/hash_generator_testing.h +++ b/absl/container/internal/hash_generator_testing.h @@ -43,7 +43,7 @@ struct IsMap> : std::true_type {}; } // namespace generator_internal -std::mt19937_64* GetThreadLocalRng(); +std::mt19937_64* GetSharedRng(); enum Enum { kEnumEmpty, @@ -66,7 +66,7 @@ template struct Generator::value>::type> { T operator()() const { std::uniform_int_distribution dist; - return dist(*GetThreadLocalRng()); + return dist(*GetSharedRng()); } }; @@ -76,7 +76,7 @@ struct Generator { std::uniform_int_distribution::type> dist; while (true) { - auto variate = dist(*GetThreadLocalRng()); + auto variate = dist(*GetSharedRng()); if (variate != kEnumEmpty && variate != kEnumDeleted) return static_cast(variate); } @@ -90,7 +90,7 @@ struct Generator { typename std::underlying_type::type> dist; while (true) { - EnumClass variate = static_cast(dist(*GetThreadLocalRng())); + EnumClass variate = static_cast(dist(*GetSharedRng())); if (variate != EnumClass::kEmpty && variate != EnumClass::kDeleted) return static_cast(variate); } diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h index 00710e52..18d3f28f 100644 --- a/absl/container/node_hash_map.h +++ b/absl/container/node_hash_map.h @@ -40,6 +40,7 @@ #include #include +#include "absl/algorithm/container.h" #include "absl/container/internal/container_memory.h" #include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/node_hash_policy.h" @@ -91,7 +92,7 @@ class NodeHashMapPolicy; // std::string search_key = "b"; // auto result = ducks.find(search_key); // if (result != ducks.end()) { -// std::cout << "Result: " << search_key->second << std::endl; +// std::cout << "Result: " << result->second << std::endl; // } template , @@ -566,5 +567,16 @@ class NodeHashMapPolicy static const Value& value(const value_type* elem) { return elem->second; } }; } // namespace container_internal + +namespace container_algorithm_internal { + +// Specialization of trait in absl/algorithm/container.h +template +struct IsUnorderedContainer< + absl::node_hash_map> : std::true_type {}; + +} // namespace container_algorithm_internal + } // namespace absl + #endif // ABSL_CONTAINER_NODE_HASH_MAP_H_ diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h index 813fdeff..e0897c99 100644 --- a/absl/container/node_hash_set.h +++ b/absl/container/node_hash_set.h @@ -37,6 +37,7 @@ #include +#include "absl/algorithm/container.h" #include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export #include "absl/container/internal/node_hash_policy.h" #include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export @@ -475,5 +476,15 @@ struct NodeHashSetPolicy static size_t element_space_used(const T*) { return sizeof(T); } }; } // namespace container_internal + +namespace container_algorithm_internal { + +// Specialization of trait in absl/algorithm/container.h +template +struct IsUnorderedContainer> + : std::true_type {}; + +} // namespace container_algorithm_internal } // namespace absl + #endif // ABSL_CONTAINER_NODE_HASH_SET_H_ diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 5d14a4a8..9c2e00f6 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h @@ -37,6 +37,11 @@ #include "absl/base/macros.h" #include "absl/base/port.h" +#if defined(_MSC_VER) && defined(_WIN64) +#include +#pragma intrinsic(_umul128) +#endif // defined(_MSC_VER) && defined(_WIN64) + namespace absl { @@ -661,6 +666,12 @@ inline uint128 operator*(uint128 lhs, uint128 rhs) { // can be used for uint128 storage. return static_cast(lhs) * static_cast(rhs); +#elif defined(_MSC_VER) && defined(_WIN64) + uint64_t carry; + uint64_t low = _umul128(Uint128Low64(lhs), Uint128Low64(rhs), &carry); + return MakeUint128(Uint128Low64(lhs) * Uint128High64(rhs) + + Uint128High64(lhs) * Uint128Low64(rhs) + carry, + low); #else // ABSL_HAVE_INTRINSIC128 uint64_t a32 = Uint128Low64(lhs) >> 32; uint64_t a00 = Uint128Low64(lhs) & 0xffffffff; diff --git a/absl/synchronization/lifetime_test.cc b/absl/synchronization/lifetime_test.cc index 90c9009b..b7360c29 100644 --- a/absl/synchronization/lifetime_test.cc +++ b/absl/synchronization/lifetime_test.cc @@ -72,23 +72,19 @@ void ThreadTwo(absl::Mutex* mutex, absl::CondVar* condvar, // Launch thread 1 and thread 2, and block on their completion. // If any of 'mutex', 'condvar', or 'notification' is nullptr, use a locally // constructed instance instead. -void RunTests(absl::Mutex* mutex, absl::CondVar* condvar, - absl::Notification* notification) { +void RunTests(absl::Mutex* mutex, absl::CondVar* condvar) { absl::Mutex default_mutex; absl::CondVar default_condvar; - absl::Notification default_notification; + absl::Notification notification; if (!mutex) { mutex = &default_mutex; } if (!condvar) { condvar = &default_condvar; } - if (!notification) { - notification = &default_notification; - } bool state = false; - std::thread thread_one(ThreadOne, mutex, condvar, notification, &state); - std::thread thread_two(ThreadTwo, mutex, condvar, notification, &state); + std::thread thread_one(ThreadOne, mutex, condvar, ¬ification, &state); + std::thread thread_two(ThreadTwo, mutex, condvar, ¬ification, &state); thread_one.join(); thread_two.join(); } @@ -96,8 +92,7 @@ void RunTests(absl::Mutex* mutex, absl::CondVar* condvar, void TestLocals() { absl::Mutex mutex; absl::CondVar condvar; - absl::Notification notification; - RunTests(&mutex, &condvar, ¬ification); + RunTests(&mutex, &condvar); } // Global variables during start and termination diff --git a/absl/synchronization/notification.cc b/absl/synchronization/notification.cc index ed8cc906..cdcbc134 100644 --- a/absl/synchronization/notification.cc +++ b/absl/synchronization/notification.cc @@ -22,6 +22,7 @@ #include "absl/time/time.h" namespace absl { + void Notification::Notify() { MutexLock l(&this->mutex_); diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc index 7ae25dc6..775da91e 100644 --- a/absl/time/duration_test.cc +++ b/absl/time/duration_test.cc @@ -56,6 +56,17 @@ MATCHER_P(TimevalMatcher, tv, "") { return false; } +TEST(Duration, ConstExpr) { + constexpr absl::Duration d0 = absl::ZeroDuration(); + static_assert(d0 == absl::ZeroDuration(), "ZeroDuration()"); + constexpr absl::Duration d1 = absl::Seconds(1); + static_assert(d1 == absl::Seconds(1), "Seconds(1)"); + static_assert(d1 != absl::ZeroDuration(), "Seconds(1)"); + constexpr absl::Duration d2 = absl::InfiniteDuration(); + static_assert(d2 == absl::InfiniteDuration(), "InfiniteDuration()"); + static_assert(d2 != absl::ZeroDuration(), "InfiniteDuration()"); +} + TEST(Duration, ValueSemantics) { // If this compiles, the test passes. constexpr absl::Duration a; // Default construction diff --git a/absl/time/internal/cctz/src/time_zone_libc.cc b/absl/time/internal/cctz/src/time_zone_libc.cc index e35fa18b..6db519e1 100644 --- a/absl/time/internal/cctz/src/time_zone_libc.cc +++ b/absl/time/internal/cctz/src/time_zone_libc.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -85,6 +86,76 @@ OffsetAbbr get_offset_abbr(const T& tm, decltype(&T::__tm_gmtoff) = nullptr, #endif // !defined(__tm_gmtoff) && !defined(__tm_zone) #endif +inline std::tm* gm_time(const std::time_t *timep, std::tm *result) { +#if defined(_WIN32) || defined(_WIN64) + return gmtime_s(result, timep) ? nullptr : result; +#else + return gmtime_r(timep, result); +#endif +} + +inline std::tm* local_time(const std::time_t *timep, std::tm *result) { +#if defined(_WIN32) || defined(_WIN64) + return localtime_s(result, timep) ? nullptr : result; +#else + return localtime_r(timep, result); +#endif +} + +// Converts a civil second and "dst" flag into a time_t and UTC offset. +// Returns false if time_t cannot represent the requested civil second. +// Caller must have already checked that cs.year() will fit into a tm_year. +bool make_time(const civil_second& cs, int is_dst, std::time_t* t, int* off) { + std::tm tm; + tm.tm_year = static_cast(cs.year() - year_t{1900}); + tm.tm_mon = cs.month() - 1; + tm.tm_mday = cs.day(); + tm.tm_hour = cs.hour(); + tm.tm_min = cs.minute(); + tm.tm_sec = cs.second(); + tm.tm_isdst = is_dst; + *t = std::mktime(&tm); + if (*t == std::time_t{-1}) { + std::tm tm2; + const std::tm* tmp = local_time(t, &tm2); + if (tmp == nullptr || tmp->tm_year != tm.tm_year || + tmp->tm_mon != tm.tm_mon || tmp->tm_mday != tm.tm_mday || + tmp->tm_hour != tm.tm_hour || tmp->tm_min != tm.tm_min || + tmp->tm_sec != tm.tm_sec) { + // A true error (not just one second before the epoch). + return false; + } + } + *off = get_offset_abbr(tm).first; + return true; +} + +// Find the least time_t in [lo:hi] where local time matches offset, given: +// (1) lo doesn't match, (2) hi does, and (3) there is only one transition. +std::time_t find_trans(std::time_t lo, std::time_t hi, int offset) { + std::tm tm; + while (lo + 1 != hi) { + const std::time_t mid = lo + (hi - lo) / 2; + if (std::tm* tmp = local_time(&mid, &tm)) { + if (get_offset_abbr(*tmp).first == offset) { + hi = mid; + } else { + lo = mid; + } + } else { + // If std::tm cannot hold some result we resort to a linear search, + // ignoring all failed conversions. Slow, but never really happens. + while (++lo != hi) { + if (std::tm* tmp = local_time(&lo, &tm)) { + if (get_offset_abbr(*tmp).first == offset) break; + } + } + return lo; + } + } + return hi; +} + } // namespace TimeZoneLibC::TimeZoneLibC(const std::string& name) @@ -93,50 +164,107 @@ TimeZoneLibC::TimeZoneLibC(const std::string& name) time_zone::absolute_lookup TimeZoneLibC::BreakTime( const time_point& tp) const { time_zone::absolute_lookup al; - std::time_t t = ToUnixSeconds(tp); + al.offset = 0; + al.is_dst = false; + al.abbr = "-00"; + + const std::int_fast64_t s = ToUnixSeconds(tp); + + // If std::time_t cannot hold the input we saturate the output. + if (s < std::numeric_limits::min()) { + al.cs = civil_second::min(); + return al; + } + if (s > std::numeric_limits::max()) { + al.cs = civil_second::max(); + return al; + } + + const std::time_t t = static_cast(s); std::tm tm; - if (local_) { -#if defined(_WIN32) || defined(_WIN64) - localtime_s(&tm, &t); -#else - localtime_r(&t, &tm); -#endif - std::tie(al.offset, al.abbr) = get_offset_abbr(tm); - } else { -#if defined(_WIN32) || defined(_WIN64) - gmtime_s(&tm, &t); -#else - gmtime_r(&t, &tm); -#endif - al.offset = 0; - al.abbr = "UTC"; + std::tm* tmp = local_ ? local_time(&t, &tm) : gm_time(&t, &tm); + + // If std::tm cannot hold the result we saturate the output. + if (tmp == nullptr) { + al.cs = (s < 0) ? civil_second::min() : civil_second::max(); + return al; } - al.cs = civil_second(tm.tm_year + year_t{1900}, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); - al.is_dst = tm.tm_isdst > 0; + + const year_t year = tmp->tm_year + year_t{1900}; + al.cs = civil_second(year, tmp->tm_mon + 1, tmp->tm_mday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + std::tie(al.offset, al.abbr) = get_offset_abbr(*tmp); + if (!local_) al.abbr = "UTC"; // as expected by cctz + al.is_dst = tmp->tm_isdst > 0; return al; } time_zone::civil_lookup TimeZoneLibC::MakeTime(const civil_second& cs) const { - time_zone::civil_lookup cl; - std::time_t t; - if (local_) { - // Does not handle SKIPPED/AMBIGUOUS or huge years. - std::tm tm; - tm.tm_year = static_cast(cs.year() - 1900); - tm.tm_mon = cs.month() - 1; - tm.tm_mday = cs.day(); - tm.tm_hour = cs.hour(); - tm.tm_min = cs.minute(); - tm.tm_sec = cs.second(); - tm.tm_isdst = -1; - t = std::mktime(&tm); + if (!local_) { + // If time_point cannot hold the result we saturate. + static const civil_second min_tp_cs = + civil_second() + ToUnixSeconds(time_point::min()); + static const civil_second max_tp_cs = + civil_second() + ToUnixSeconds(time_point::max()); + const time_point tp = + (cs < min_tp_cs) + ? time_point::min() + : (cs > max_tp_cs) ? time_point::max() + : FromUnixSeconds(cs - civil_second()); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + } + + // If tm_year cannot hold the requested year we saturate the result. + if (cs.year() < 0) { + if (cs.year() < std::numeric_limits::min() + year_t{1900}) { + const time_point tp = time_point::min(); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + } } else { - t = cs - civil_second(); + if (cs.year() - year_t{1900} > std::numeric_limits::max()) { + const time_point tp = time_point::max(); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + } + } + + // We probe with "is_dst" values of 0 and 1 to try to distinguish unique + // civil seconds from skipped or repeated ones. This is not always possible + // however, as the "dst" flag does not change over some offset transitions. + // We are also subject to the vagaries of mktime() implementations. + std::time_t t0, t1; + int offset0, offset1; + if (make_time(cs, 0, &t0, &offset0) && make_time(cs, 1, &t1, &offset1)) { + if (t0 == t1) { + // The civil time was singular (pre == trans == post). + const time_point tp = FromUnixSeconds(t0); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; + } + + if (t0 > t1) { + std::swap(t0, t1); + std::swap(offset0, offset1); + } + const std::time_t tt = find_trans(t0, t1, offset1); + const time_point trans = FromUnixSeconds(tt); + + if (offset0 < offset1) { + // The civil time did not exist (pre >= trans > post). + const time_point pre = FromUnixSeconds(t1); + const time_point post = FromUnixSeconds(t0); + return {time_zone::civil_lookup::SKIPPED, pre, trans, post}; + } + + // The civil time was ambiguous (pre < trans <= post). + const time_point pre = FromUnixSeconds(t0); + const time_point post = FromUnixSeconds(t1); + return {time_zone::civil_lookup::REPEATED, pre, trans, post}; } - cl.kind = time_zone::civil_lookup::UNIQUE; - cl.pre = cl.trans = cl.post = FromUnixSeconds(t); - return cl; + + // make_time() failed somehow so we saturate the result. + const time_point tp = (cs < civil_second()) + ? time_point::min() + : time_point::max(); + return {time_zone::civil_lookup::UNIQUE, tp, tp, tp}; } bool TimeZoneLibC::NextTransition(const time_point& tp, diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc index f28e7f85..e84b9469 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc @@ -16,7 +16,9 @@ #include #include +#include #include +#include #include #include #include @@ -925,7 +927,7 @@ TEST(MakeTime, Normalization) { EXPECT_EQ(tp, convert(civil_second(2009, 2, 13, 18, 30, 90), tz)); // second } -// NOTE: Run this with --copt=-ftrapv to detect overflow problems. +// NOTE: Run this with -ftrapv to detect overflow problems. TEST(MakeTime, SysSecondsLimits) { const char RFC3339[] = "%Y-%m-%dT%H:%M:%S%Ez"; const time_zone utc = utc_time_zone(); @@ -991,19 +993,107 @@ TEST(MakeTime, SysSecondsLimits) { tp = convert(civil_second::min(), west); EXPECT_EQ(time_point::min(), tp); + // Some similar checks for the "libc" time-zone implementation. if (sizeof(std::time_t) >= 8) { // Checks that "tm_year + 1900", as used by the "libc" implementation, // can produce year values beyond the range on an int without overflow. #if defined(_WIN32) || defined(_WIN64) - // localtime_s() and gmtime_s() don't believe in years past 3000. + // localtime_s() and gmtime_s() don't believe in years outside [1970:3000]. #else - const time_zone libc_utc = LoadZone("libc:UTC"); - tp = convert(civil_year(year_t{2147483648}), libc_utc); - EXPECT_EQ("2147483648-01-01T00:00:00+00:00", format(RFC3339, tp, libc_utc)); + const time_zone utc = LoadZone("libc:UTC"); + const year_t max_tm_year = year_t{std::numeric_limits::max()} + 1900; + tp = convert(civil_second(max_tm_year, 12, 31, 23, 59, 59), utc); + EXPECT_EQ("2147485547-12-31T23:59:59+00:00", format(RFC3339, tp, utc)); + const year_t min_tm_year = year_t{std::numeric_limits::min()} + 1900; + tp = convert(civil_second(min_tm_year, 1, 1, 0, 0, 0), utc); + EXPECT_EQ("-2147481748-01-01T00:00:00+00:00", format(RFC3339, tp, utc)); #endif } } +TEST(MakeTime, LocalTimeLibC) { + // Checks that cctz and libc agree on transition points in [1970:2037]. + // + // We limit this test case to environments where: + // 1) we know how to change the time zone used by localtime()/mktime(), + // 2) cctz and localtime()/mktime() will use similar-enough tzdata, and + // 3) we have some idea about how mktime() behaves during transitions. +#if defined(__linux__) + const char* const ep = getenv("TZ"); + std::string tz_name = (ep != nullptr) ? ep : ""; + for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) { + ASSERT_EQ(0, setenv("TZ", *np, 1)); // change what "localtime" means + const auto zi = local_time_zone(); + const auto lc = LoadZone("libc:localtime"); + time_zone::civil_transition trans; + for (auto tp = zi.lookup(civil_second()).trans; + zi.next_transition(tp, &trans); + tp = zi.lookup(trans.to).trans) { + const auto fcl = zi.lookup(trans.from); + const auto tcl = zi.lookup(trans.to); + civil_second cs; // compare cs in zi and lc + if (fcl.kind == time_zone::civil_lookup::UNIQUE) { + if (tcl.kind == time_zone::civil_lookup::UNIQUE) { + // Both unique; must be an is_dst or abbr change. + ASSERT_EQ(trans.from, trans.to); + const auto trans = fcl.trans; + const auto tal = zi.lookup(trans); + const auto tprev = trans - absl::time_internal::cctz::seconds(1); + const auto pal = zi.lookup(tprev); + if (pal.is_dst == tal.is_dst) { + ASSERT_STRNE(pal.abbr, tal.abbr); + } + continue; + } + ASSERT_EQ(time_zone::civil_lookup::REPEATED, tcl.kind); + cs = trans.to; + } else { + ASSERT_EQ(time_zone::civil_lookup::UNIQUE, tcl.kind); + ASSERT_EQ(time_zone::civil_lookup::SKIPPED, fcl.kind); + cs = trans.from; + } + if (cs.year() > 2037) break; // limit test time (and to 32-bit time_t) + const auto cl_zi = zi.lookup(cs); + if (zi.lookup(cl_zi.pre).is_dst == zi.lookup(cl_zi.post).is_dst) { + // The "libc" implementation cannot correctly classify transitions + // that don't change the "tm_isdst" flag. In Europe/Volgograd, for + // example, there is a SKIPPED transition from +03 to +04 with dst=F + // on both sides ... + // 1540681199 = 2018-10-28 01:59:59 +03:00:00 [dst=F off=10800] + // 1540681200 = 2018-10-28 03:00:00 +04:00:00 [dst=F off=14400] + // but std::mktime(2018-10-28 02:00:00, tm_isdst=0) fails, unlike, + // say, the similar Europe/Chisinau transition from +02 to +03 ... + // 1521935999 = 2018-03-25 01:59:59 +02:00:00 [dst=F off=7200] + // 1521936000 = 2018-03-25 03:00:00 +03:00:00 [dst=T off=10800] + // where std::mktime(2018-03-25 02:00:00, tm_isdst=0) succeeds and + // returns 1521936000. + continue; + } + if (cs == civil_second(2037, 10, 4, 2, 0, 0)) { + const std::string tzname = *np; + if (tzname == "Africa/Casablanca" || tzname == "Africa/El_Aaiun") { + // The "libc" implementation gets this transition wrong (at least + // until 2018g when it was removed), returning an offset of 3600 + // instead of 0. TODO: Revert this when 2018g is ubiquitous. + continue; + } + } + const auto cl_lc = lc.lookup(cs); + SCOPED_TRACE(testing::Message() << "For " << cs << " in " << *np); + EXPECT_EQ(cl_zi.kind, cl_lc.kind); + EXPECT_EQ(cl_zi.pre, cl_lc.pre); + EXPECT_EQ(cl_zi.trans, cl_lc.trans); + EXPECT_EQ(cl_zi.post, cl_lc.post); + } + } + if (ep == nullptr) { + ASSERT_EQ(0, unsetenv("TZ")); + } else { + ASSERT_EQ(0, setenv("TZ", tz_name.c_str(), 1)); + } +#endif +} + TEST(NextTransition, UTC) { const auto tz = utc_time_zone(); time_zone::civil_transition trans; diff --git a/absl/time/time.h b/absl/time/time.h index e9e989cb..de12e560 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -153,6 +153,16 @@ class Duration { // Value semantics. constexpr Duration() : rep_hi_(0), rep_lo_(0) {} // zero-length duration + // Copyable. +#if !defined(__clang__) && defined(_MSC_VER) && _MSC_VER < 1910 + // Explicitly defining the constexpr copy constructor avoids an MSVC bug. + constexpr Duration(const Duration& d) + : rep_hi_(d.rep_hi_), rep_lo_(d.rep_lo_) {} +#else + constexpr Duration(const Duration& d) = default; +#endif + Duration& operator=(const Duration& d) = default; + // Compound assignment operators. Duration& operator+=(Duration d); Duration& operator-=(Duration d); @@ -584,7 +594,11 @@ class Time { // absl::Time t = absl::Now(); // absl::Time t = absl::TimeFromTimeval(tv); // absl::Time t = absl::InfinitePast(); - constexpr Time() {} + constexpr Time() = default; + + // Copyable. + constexpr Time(const Time& t) = default; + Time& operator=(const Time& t) = default; // Assignment operators. Time& operator+=(Duration d) { @@ -826,6 +840,8 @@ class TimeZone { public: explicit TimeZone(time_internal::cctz::time_zone tz) : cz_(tz) {} TimeZone() = default; // UTC, but prefer UTCTimeZone() to be explicit. + + // Copyable. TimeZone(const TimeZone&) = default; TimeZone& operator=(const TimeZone&) = default; diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel index 43899ca7..d56fea6e 100644 --- a/absl/types/BUILD.bazel +++ b/absl/types/BUILD.bazel @@ -287,6 +287,7 @@ cc_test( linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, deps = [ ":variant", + "//absl/base:config", "//absl/base:exception_safety_testing", "//absl/memory", "@com_google_googletest//:gtest_main", diff --git a/absl/types/variant_exception_safety_test.cc b/absl/types/variant_exception_safety_test.cc index 58436f07..82425dbd 100644 --- a/absl/types/variant_exception_safety_test.cc +++ b/absl/types/variant_exception_safety_test.cc @@ -11,6 +11,7 @@ // 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. + #include "absl/types/variant.h" #include @@ -20,8 +21,11 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/base/config.h" #include "absl/base/internal/exception_safety_testing.h" #include "absl/memory/memory.h" +// See comment in absl/base/config.h +#if !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE) namespace absl { namespace { @@ -506,3 +510,5 @@ TEST(VariantExceptionSafetyTest, Swap) { } // namespace } // namespace absl + +#endif // !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE) diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc index 626d5e61..f47f3a72 100644 --- a/absl/types/variant_test.cc +++ b/absl/types/variant_test.cc @@ -559,9 +559,14 @@ TEST(VariantTest, TestDtor) { } #ifdef ABSL_HAVE_EXCEPTIONS - +// See comment in absl/base/config.h +#if defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE) +TEST(VariantTest, DISABLED_TestDtorValuelessByException) +#else // Test destruction when in the valueless_by_exception state. -TEST(VariantTest, TestDtorValuelessByException) { +TEST(VariantTest, TestDtorValuelessByException) +#endif +{ int counter = 0; IncrementInDtor counter_adjuster(&counter); -- cgit v1.2.3 From a06c4a1d9093137b7217a5aaba8920d62e835dc0 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 15 Nov 2018 11:55:00 -0800 Subject: Export of internal Abseil changes. -- 5f1ab09522226336830d9ea6ef7276d37f536ac5 by Abseil Team : Clarify the documentation of ABSL_MUST_USE_RESULT. PiperOrigin-RevId: 221663609 -- af4c8359a20d56369fd1dce318220cf3be03ca66 by Greg Falcon : Internal change PiperOrigin-RevId: 221538448 -- 487cd09bd1942bf607080deeae38fee6ce66f294 by Eric Fiselier : Work around emscripten bugs and missing features in absl/time:time_test. The emscripten toolchain has a couple of issues that cause time_test to fail. Specifically: 1) emscripten doesn't support signals. 2) The javascript implementation of strftime/strptime use different expansions of '%c' that mean it doesn't round-trip. PiperOrigin-RevId: 221523701 -- 5823652e6a200b97b07334bc47128dfac40e20fc by Xiaoyi Zhang : Fix MSVC compiler warning by explicitly casting to char. Currently our MSVC build breaks with the following error: raw_hash_set.h(406): warning C4309: 'argument': truncation of constant value PiperOrigin-RevId: 221492585 -- c5806358320711a5efbe5c523df13e14ab53a17d by Greg Falcon : Replace calls to getpagesize() with the more portable sysconf(_SC_PAGESIZE); the latter is in POSIX 1.0 and is called out in the Linux `getpagesize` man page as a more portable spelling. PiperOrigin-RevId: 221492471 -- 19ffe82851072229bb7ce73f754ffe4c18e8c575 by Abseil Team : Fix -Wundef error in absl/hash/internal/hash.h. PiperOrigin-RevId: 221444120 -- b30f3d0a848563b6e4ec33f3dc085831dfabb748 by Jon Cohen : Import of CCTZ from GitHub. PiperOrigin-RevId: 221339736 GitOrigin-RevId: 5f1ab09522226336830d9ea6ef7276d37f536ac5 Change-Id: I96223d522d98bf6616dea88eb047c2d536eeddd0 --- absl/base/attributes.h | 25 ++++++++++++++++------ absl/base/config.h | 5 ++++- absl/base/internal/direct_mmap.h | 2 +- absl/base/internal/low_level_alloc.cc | 4 ++-- absl/container/internal/raw_hash_set.h | 2 +- absl/debugging/failure_signal_handler.cc | 2 +- absl/debugging/symbolize_elf.inc | 2 +- absl/hash/internal/hash.h | 10 +++++---- absl/time/format_test.cc | 9 ++++++-- .../internal/cctz/include/cctz/civil_time_detail.h | 10 +++++---- 10 files changed, 47 insertions(+), 24 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/attributes.h b/absl/base/attributes.h index c44b8828..291ad89e 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -402,17 +402,28 @@ // ABSL_MUST_USE_RESULT // -// Tells the compiler to warn about unused return values for functions declared -// with this macro. The macro must appear as the very first part of a function -// declaration or definition: +// Tells the compiler to warn about unused results. // -// Example: +// When annotating a function, it must appear as the first part of the +// declaration or definition. The compiler will warn if the return value from +// such a function is unused: // // ABSL_MUST_USE_RESULT Sprocket* AllocateSprocket(); +// AllocateSprocket(); // Triggers a warning. +// +// When annotating a class, it is equivalent to annotating every function which +// returns an instance. +// +// class ABSL_MUST_USE_RESULT Sprocket {}; +// Sprocket(); // Triggers a warning. +// +// Sprocket MakeSprocket(); +// MakeSprocket(); // Triggers a warning. +// +// Note that references and pointers are not instances: // -// This placement has the broadest compatibility with GCC, Clang, and MSVC, with -// both defs and decls, and with GCC-style attributes, MSVC declspec, C++11 -// and C++17 attributes. +// Sprocket* SprocketPointer(); +// SprocketPointer(); // Does *not* trigger a warning. // // ABSL_MUST_USE_RESULT allows using cast-to-void to suppress the unused result // warning. For that, warn_unused_result is used only for clang but not for gcc. diff --git a/absl/base/config.h b/absl/base/config.h index e3edb2bf..ca089f6d 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -274,7 +274,8 @@ #error ABSL_HAVE_MMAP cannot be directly set #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \ - defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) + defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) || \ + defined(__ASYLO__) #define ABSL_HAVE_MMAP 1 #endif @@ -328,6 +329,8 @@ #define ABSL_HAVE_ALARM 1 #elif defined(_MSC_VER) // feature tests for Microsoft's library +#elif defined(__EMSCRIPTEN__) +// emscripten doesn't support signals #elif defined(__native_client__) #else // other standard libraries diff --git a/absl/base/internal/direct_mmap.h b/absl/base/internal/direct_mmap.h index 0426e118..3e5368db 100644 --- a/absl/base/internal/direct_mmap.h +++ b/absl/base/internal/direct_mmap.h @@ -75,7 +75,7 @@ inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd, // On these architectures, implement mmap with mmap2. static int pagesize = 0; if (pagesize == 0) { - pagesize = getpagesize(); + pagesize = sysconf(_SC_PAGESIZE); } if (offset < 0 || offset % pagesize != 0) { errno = EINVAL; diff --git a/absl/base/internal/low_level_alloc.cc b/absl/base/internal/low_level_alloc.cc index 6e636a02..015edf8d 100644 --- a/absl/base/internal/low_level_alloc.cc +++ b/absl/base/internal/low_level_alloc.cc @@ -208,7 +208,7 @@ struct LowLevelAlloc::Arena { int32_t allocation_count GUARDED_BY(mu); // flags passed to NewArena const uint32_t flags; - // Result of getpagesize() + // Result of sysconf(_SC_PAGESIZE) const size_t pagesize; // Lowest power of two >= max(16, sizeof(AllocList)) const size_t roundup; @@ -325,7 +325,7 @@ size_t GetPageSize() { GetSystemInfo(&system_info); return std::max(system_info.dwPageSize, system_info.dwAllocationGranularity); #else - return getpagesize(); + return sysconf(_SC_PAGESIZE); #endif } diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 10fa3d85..575f1b00 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -403,7 +403,7 @@ struct GroupSse2Impl { } void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const { - auto msbs = _mm_set1_epi8(0x80); + auto msbs = _mm_set1_epi8(static_cast(-128)); auto x126 = _mm_set1_epi8(126); #if SWISSTABLE_HAVE_SSSE3 auto res = _mm_or_si128(_mm_shuffle_epi8(x126, ctrl), msbs); diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc index d4b957bc..6cecd93f 100644 --- a/absl/debugging/failure_signal_handler.cc +++ b/absl/debugging/failure_signal_handler.cc @@ -119,7 +119,7 @@ const char* FailureSignalToString(int signo) { #ifndef _WIN32 static bool SetupAlternateStackOnce() { - const size_t page_mask = getpagesize() - 1; + const size_t page_mask = sysconf(_SC_PAGESIZE) - 1; size_t stack_size = (std::max(SIGSTKSZ, 65536) + page_mask) & ~page_mask; #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ defined(THREAD_SANITIZER) diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc index e21439ce..b31362e6 100644 --- a/absl/debugging/symbolize_elf.inc +++ b/absl/debugging/symbolize_elf.inc @@ -333,7 +333,7 @@ static std::atomic g_cached_symbolizer; } // namespace static int SymbolizerSize() { - int pagesize = getpagesize(); + int pagesize = sysconf(_SC_PAGESIZE); return ((sizeof(Symbolizer) - 1) / pagesize + 1) * pagesize; } diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index b66cc1b5..6c00f354 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -303,13 +303,13 @@ H hash_tuple(H hash_state, const Tuple& t, absl::index_sequence) { // AbslHashValue for hashing tuples template -#if _MSC_VER +#if defined(_MSC_VER) // This SFINAE gets MSVC confused under some conditions. Let's just disable it // for now. H -#else +#else // _MSC_VER typename std::enable_if...>::value, H>::type -#endif +#endif // _MSC_VER AbslHashValue(H hash_state, const std::tuple& t) { return hash_internal::hash_tuple(std::move(hash_state), t, absl::make_index_sequence()); @@ -545,7 +545,7 @@ hash_range_or_bytes(H hash_state, const T* data, size_t size) { // In MSVC we can't probe std::hash or stdext::hash because it triggers a // static_assert instead of failing substitution. #if defined(_MSC_VER) -#undef ABSL_HASH_INTERNAL_CAN_POISON_ +#define ABSL_HASH_INTERNAL_CAN_POISON_ 0 #else // _MSC_VER #define ABSL_HASH_INTERNAL_CAN_POISON_ 1 #endif // _MSC_VER @@ -553,6 +553,8 @@ hash_range_or_bytes(H hash_state, const T* data, size_t size) { #if defined(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE) && \ ABSL_HASH_INTERNAL_CAN_POISON_ #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 1 +#else +#define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 0 #endif enum class InvokeHashTag { diff --git a/absl/time/format_test.cc b/absl/time/format_test.cc index 40f4c246..ac8d5ea3 100644 --- a/absl/time/format_test.cc +++ b/absl/time/format_test.cc @@ -394,7 +394,12 @@ TEST(FormatParse, RoundTrip) { // work. On Windows, `absl::ParseTime()` falls back to std::get_time() which // appears to fail on "%c" (or at least on the "%c" text produced by // `strftime()`). This makes it fail the round-trip test. -#ifndef _MSC_VER + // + // Under the emscripten compiler `absl::ParseTime() falls back to + // `strptime()`, but that ends up using a different definition for "%c" + // compared to `strftime()`, also causing the round-trip test to fail + // (see https://github.com/kripken/emscripten/pull/7491). +#if !defined(_MSC_VER) && !defined(__EMSCRIPTEN__) // Even though we don't know what %c will produce, it should roundtrip, // but only in the 0-offset timezone. { @@ -403,7 +408,7 @@ TEST(FormatParse, RoundTrip) { EXPECT_TRUE(absl::ParseTime("%c", s, &out, &err)) << s << ": " << err; EXPECT_EQ(in, out); } -#endif // _MSC_VER +#endif // !_MSC_VER && !__EMSCRIPTEN__ } TEST(FormatParse, RoundTripDistantFuture) { diff --git a/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/absl/time/internal/cctz/include/cctz/civil_time_detail.h index d7f72717..855958ec 100644 --- a/absl/time/internal/cctz/include/cctz/civil_time_detail.h +++ b/absl/time/internal/cctz/include/cctz/civil_time_detail.h @@ -506,9 +506,11 @@ enum class weekday { }; CONSTEXPR_F weekday get_weekday(const civil_day& cd) noexcept { - CONSTEXPR_D weekday k_weekday_by_sun_off[7] = { - weekday::sunday, weekday::monday, weekday::tuesday, - weekday::wednesday, weekday::thursday, weekday::friday, + CONSTEXPR_D weekday k_weekday_by_mon_off[13] = { + weekday::monday, weekday::tuesday, weekday::wednesday, + weekday::thursday, weekday::friday, weekday::saturday, + weekday::sunday, weekday::monday, weekday::tuesday, + weekday::wednesday, weekday::thursday, weekday::friday, weekday::saturday, }; CONSTEXPR_D int k_weekday_offsets[1 + 12] = { @@ -517,7 +519,7 @@ CONSTEXPR_F weekday get_weekday(const civil_day& cd) noexcept { year_t wd = 2400 + (cd.year() % 400) - (cd.month() < 3); wd += wd / 4 - wd / 100 + wd / 400; wd += k_weekday_offsets[cd.month()] + cd.day(); - return k_weekday_by_sun_off[(wd % 7 + 7) % 7]; + return k_weekday_by_mon_off[wd % 7 + 6]; } //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From f6ae816808cd913e0e2b3e2af14f328fa1071af0 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 16 Nov 2018 13:36:37 -0800 Subject: Export of internal Abseil changes. -- da04b8cd21f6225d71397471474d34a77df0efd6 by Jon Cohen : Don't use std::any, std::optional, std::variant, and friends on MacOS versions older than 10.14. Although Xcode 10 includes those headers and makes the types available to use, according to https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes, on MacOS 10.13 and earlier use of any functions (std::get, for example) results in an error message to upgrade to MacOS 10.14. This fixes https://github.com/abseil/abseil-cpp/issues/207. See that issue for more information on the error generated. PiperOrigin-RevId: 221844618 -- 1d99f77b4c60c5b0d7984f46e8ed63a3f969c635 by Jon Cohen : raw_hash_set_test is still flaky under gcc 4.8. Since we now have the probe_test, we don't need the PerfectRatio tests. Just remove them. PiperOrigin-RevId: 221843042 -- 135cbb2a5d90963256518b3b59fe6710815e5dfa by Abseil Team : Update absl/algorithm/CMakeLists.txt to use new functions i.e. absl_cc_(library|test) PiperOrigin-RevId: 221828348 -- 1a5abde4f17f998ae89d87155d59f982a70202d8 by Jon Cohen : Internal change PiperOrigin-RevId: 221708245 -- e03e031d4de39275989f695c768b0940cce1ff16 by Matt Armstrong : Log to FATAL in throw_delegate.h ABSL_RAW_LOG(FATAL, ...) is guaranteed to abort. Previously, the code was logging to ERROR and calling abort() explicitly, which defeated any integration with absl::raw_logging_internal::AbortHook(). These changes are limited to Abseil internal APIs. PiperOrigin-RevId: 221696513 -- d13691523a3f9a5367fd1194cf9604bf4a969029 by Shahriar Rouf : Import of CCTZ from GitHub. PiperOrigin-RevId: 221694877 -- f4044c56d44ba0ac2a9f218ed55f1b1f9e985eae by Abseil Team : Update absl/base/CMakeLists.txt to use new functions i.e. absl_cc_(library|test) PiperOrigin-RevId: 221676669 GitOrigin-RevId: da04b8cd21f6225d71397471474d34a77df0efd6 Change-Id: If6621e10d096a39b6a056a072c2727a0df0b0620 --- CMake/AbseilHelpers.cmake | 20 +- CMake/DownloadGTest.cmake | 2 +- absl/algorithm/CMakeLists.txt | 70 ++- absl/base/CMakeLists.txt | 574 ++++++++++----------- absl/base/config.h | 21 +- absl/base/internal/throw_delegate.cc | 4 +- absl/container/internal/raw_hash_set_test.cc | 138 ----- absl/debugging/CMakeLists.txt | 2 +- .../internal/cctz/include/cctz/civil_time_detail.h | 34 +- 9 files changed, 384 insertions(+), 481 deletions(-) (limited to 'absl/base/config.h') diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake index 3b9148ea..cc606ccb 100644 --- a/CMake/AbseilHelpers.cmake +++ b/CMake/AbseilHelpers.cmake @@ -73,11 +73,12 @@ endfunction() # DEFINES: List of public defines # LINKOPTS: List of link options # PUBLIC: Add this so that this library will be exported under absl:: (see Note). +# Also in IDE, target will appear in Abseil folder while non PUBLIC will be in Abseil/internal. # TESTONLY: When added, this target will only be built if user passes -DABSL_RUN_TESTS=ON to CMake. # # Note: # By default, absl_cc_library will always create a library named absl_internal_${NAME}, -# which means other targets can only depend this library as absl_internal_${NAME}, not ${NAME}. +# and alias target absl::${NAME}. # This is to reduce namespace pollution. # # absl_cc_library( @@ -98,7 +99,7 @@ endfunction() # ) # # If PUBLIC is set, absl_cc_library will instead create a target named -# absl_${NAME} and an alias absl::${NAME}. +# absl_${NAME} and still an alias absl::${NAME}. # # absl_cc_library( # NAME @@ -146,7 +147,13 @@ function(absl_cc_library) target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES}) # Add all Abseil targets to a a folder in the IDE for organization. - set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) + if(ABSL_CC_LIB_PUBLIC) + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) + elseif(ABSL_CC_LIB_TESTONLY) + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test) + else() + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/internal) + endif() else() # Generating header-only library add_library(${_NAME} INTERFACE) @@ -157,10 +164,7 @@ function(absl_cc_library) ) target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES}) endif() - - if(ABSL_CC_LIB_PUBLIC) - add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME}) - endif() + add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME}) endif() endfunction() @@ -231,7 +235,7 @@ function(absl_cc_test) PRIVATE ${ABSL_CC_TEST_LINKOPTS} ) # Add all Abseil targets to a a folder in the IDE for organization. - set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test) add_test(NAME ${_NAME} COMMAND ${_NAME}) endfunction() diff --git a/CMake/DownloadGTest.cmake b/CMake/DownloadGTest.cmake index 9d413215..3c682aef 100644 --- a/CMake/DownloadGTest.cmake +++ b/CMake/DownloadGTest.cmake @@ -4,7 +4,7 @@ # Download the latest googletest from Github master configure_file( ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt.in - googletest-download/CMakeLists.txt + ${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt ) # Configure and build the downloaded googletest source diff --git a/absl/algorithm/CMakeLists.txt b/absl/algorithm/CMakeLists.txt index fdf45c55..6608f184 100644 --- a/absl/algorithm/CMakeLists.txt +++ b/absl/algorithm/CMakeLists.txt @@ -14,50 +14,46 @@ # limitations under the License. # -list(APPEND ALGORITHM_PUBLIC_HEADERS - "algorithm.h" - "container.h" -) - - -# -## TESTS -# - -# test algorithm_test -list(APPEND ALGORITHM_TEST_SRC - "algorithm_test.cc" - ${ALGORITHM_PUBLIC_HEADERS} - ${ALGORITHM_INTERNAL_HEADERS} -) - -absl_header_library( - TARGET - absl_algorithm - EXPORT_NAME +absl_cc_library( + NAME algorithm + HDRS + "algorithm.h" + PUBLIC ) -absl_test( - TARGET +absl_cc_test( + NAME algorithm_test - SOURCES - ${ALGORITHM_TEST_SRC} - PUBLIC_LIBRARIES + SRCS + "algorithm_test.cc" + DEPS absl::algorithm + gmock_main ) +absl_cc_library( + NAME + algorithm_container + HDRS + "container.h" + DEPS + absl::algorithm + absl::core_headers + absl::meta + PUBLIC +) - - -# test container_test -set(CONTAINER_TEST_SRC "container_test.cc") - -absl_test( - TARGET +absl_cc_test( + NAME container_test - SOURCES - ${CONTAINER_TEST_SRC} - PUBLIC_LIBRARIES - absl::algorithm + SRCS + "container_test.cc" + DEPS + absl::algorithm_container + absl::base + absl::core_headers + absl::memory + absl::span + gmock_main ) diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index d506bc47..04dbf39e 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -14,90 +14,147 @@ # limitations under the License. # -list(APPEND BASE_PUBLIC_HEADERS - "attributes.h" - "call_once.h" - "casts.h" - "config.h" - "dynamic_annotations.h" - "log_severity.h" - "macros.h" - "optimization.h" - "policy_checks.h" - "port.h" - "thread_annotations.h" +absl_cc_library( + NAME + spinlock_wait + HDRS + "internal/scheduling_mode.h" + "internal/spinlock_wait.h" + SRCS + "internal/spinlock_akaros.inc" + "internal/spinlock_linux.inc" + "internal/spinlock_posix.inc" + "internal/spinlock_wait.cc" + "internal/spinlock_win32.inc" + DEPS + absl::core_headers ) +absl_cc_library( + NAME + config + HDRS + "config.h" + "policy_checks.h" + PUBLIC +) -list(APPEND BASE_INTERNAL_HEADERS - "internal/atomic_hook.h" - "internal/bits.h" - "internal/cycleclock.h" - "internal/direct_mmap.h" - "internal/endian.h" - "internal/exception_testing.h" - "internal/exception_safety_testing.h" - "internal/hide_ptr.h" - "internal/identity.h" - "internal/invoke.h" - "internal/inline_variable.h" - "internal/low_level_alloc.h" - "internal/low_level_scheduling.h" - "internal/per_thread_tls.h" - "internal/pretty_function.h" - "internal/raw_logging.h" - "internal/scheduling_mode.h" - "internal/spinlock.h" - "internal/spinlock_wait.h" - "internal/sysinfo.h" - "internal/thread_identity.h" - "internal/throw_delegate.h" - "internal/tsan_mutex_interface.h" - "internal/unaligned_access.h" - "internal/unscaledcycleclock.h" +absl_cc_library( + NAME + dynamic_annotations + HDRS + "dynamic_annotations.h" + SRCS + "dynamic_annotations.cc" + DEFINES + "__CLANG_SUPPORT_DYN_ANNOTATION__" + PUBLIC ) +absl_cc_library( + NAME + core_headers + HDRS + "attributes.h" + "macros.h" + "optimization.h" + "port.h" + "thread_annotations.h" + DEPS + absl::config + PUBLIC +) -# absl_base main library -list(APPEND BASE_SRC - "internal/cycleclock.cc" - "internal/raw_logging.cc" - "internal/spinlock.cc" - "internal/sysinfo.cc" - "internal/thread_identity.cc" - "internal/unscaledcycleclock.cc" - "internal/low_level_alloc.cc" - ${BASE_PUBLIC_HEADERS} - ${BASE_INTERNAL_HEADERS} +absl_cc_library( + NAME + malloc_internal + HDRS + "internal/direct_mmap.h" + "internal/low_level_alloc.h" + SRCS + "internal/low_level_alloc.cc" + DEPS + absl::base + absl::config + absl::core_headers + absl::dynamic_annotations + absl::spinlock_wait ) -absl_library( - TARGET - absl_base - SOURCES - ${BASE_SRC} - PUBLIC_LIBRARIES - absl_dynamic_annotations - absl_internal_spinlock_wait - EXPORT_NAME +absl_cc_library( + NAME + base_internal + HDRS + "internal/hide_ptr.h" + "internal/identity.h" + "internal/inline_variable.h" + "internal/invoke.h" +) + +absl_cc_library( + NAME base + HDRS + "call_once.h" + "casts.h" + "internal/atomic_hook.h" + "internal/cycleclock.h" + "internal/low_level_scheduling.h" + "internal/per_thread_tls.h" + "internal/raw_logging.h" + "internal/spinlock.h" + "internal/sysinfo.h" + "internal/thread_identity.h" + "internal/tsan_mutex_interface.h" + "internal/unscaledcycleclock.h" + "log_severity.h" + SRCS + "internal/cycleclock.cc" + "internal/raw_logging.cc" + "internal/spinlock.cc" + "internal/sysinfo.cc" + "internal/thread_identity.cc" + "internal/unscaledcycleclock.cc" + DEPS + absl::base_internal + absl::config + absl::core_headers + absl::dynamic_annotations + absl::spinlock_wait + PUBLIC ) absl_cc_library( NAME throw_delegate - SRCS - "internal/throw_delegate.cc" HDRS "internal/throw_delegate.h" + SRCS + "internal/throw_delegate.cc" COPTS ${ABSL_EXCEPTIONS_FLAG} DEPS absl::base ) +absl_cc_library( + NAME + exception_testing + HDRS + "internal/exception_testing.h" + DEPS + absl::config + gtest + TESTONLY +) + +absl_cc_library( + NAME + pretty_function + HDRS + "internal/pretty_function.h" +) -# exception-safety testing library absl_cc_library( NAME exception_safety_testing @@ -109,288 +166,227 @@ absl_cc_library( ${ABSL_EXCEPTIONS_FLAG} DEPS absl::base + absl::config + absl::pretty_function absl::memory absl::meta absl::strings - absl::optional + absl::utility gtest TESTONLY ) - -# dynamic_annotations library -set(DYNAMIC_ANNOTATIONS_SRC "dynamic_annotations.cc") - -absl_library( - TARGET - absl_dynamic_annotations - SOURCES - ${DYNAMIC_ANNOTATIONS_SRC} -) - -absl_cc_library( +absl_cc_test( NAME - config - HDRS - "config.h" - "policy_checks.h" - PUBLIC + absl_exception_safety_testing_test + SRCS + "exception_safety_testing_test.cc" + COPTS + ${ABSL_EXCEPTIONS_FLAG} + LINKOPTS + ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} + DEPS + absl::exception_safety_testing + absl::memory + gtest_main ) -absl_cc_library( +absl_cc_test( NAME - core_headers - HDRS - "attributes.h" - "macros.h" - "optimization.h" - "port.h" - "thread_annotations.h" + atomic_hook_test + SRCS + "internal/atomic_hook_test.cc" DEPS - absl::config - PUBLIC + absl::base + absl::core_headers + gtest_main ) -absl_cc_library( +absl_cc_test( NAME - spinlock_wait + bit_cast_test SRCS - "internal/spinlock_wait.cc" - HDRS - "internal/scheduling_mode.h" - "internal/spinlock_wait.h" + "bit_cast_test.cc" + DEPS + absl::base + absl::core_headers + gtest_main ) -absl_cc_library( +absl_cc_test( NAME - malloc_internal + throw_delegate_test SRCS - "internal/low_level_alloc.cc" - HDRS - "internal/direct_mmap.h" - "internal/low_level_alloc.h" + "throw_delegate_test.cc" DEPS - absl_dynamic_annotations -) - - - -# -## TESTS -# - -# call once test -set(ATOMIC_HOOK_TEST_SRC "internal/atomic_hook_test.cc") -set(ATOMIC_HOOK_TEST_PUBLIC_LIBRARIES absl::base) - -absl_test( - TARGET - atomic_hook_test - SOURCES - ${ATOMIC_HOOK_TEST_SRC} - PUBLIC_LIBRARIES - ${ATOMIC_HOOK_TEST_PUBLIC_LIBRARIES} -) - - -# call once test -set(CALL_ONCE_TEST_SRC "call_once_test.cc") -set(CALL_ONCE_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET - call_once_test - SOURCES - ${CALL_ONCE_TEST_SRC} - PUBLIC_LIBRARIES - ${CALL_ONCE_TEST_PUBLIC_LIBRARIES} -) - - -# test bit_cast_test -set(BIT_CAST_TEST_SRC "bit_cast_test.cc") - -absl_test( - TARGET - bit_cast_test - SOURCES - ${BIT_CAST_TEST_SRC} + absl::base + absl_internal_throw_delegate + gtest_main ) - -# test absl_throw_delegate_test -set(THROW_DELEGATE_TEST_SRC "throw_delegate_test.cc") -set(THROW_DELEGATE_TEST_PUBLIC_LIBRARIES absl::base absl_internal_throw_delegate) - -absl_test( - TARGET - throw_delegate_test - SOURCES - ${THROW_DELEGATE_TEST_SRC} - PUBLIC_LIBRARIES - ${THROW_DELEGATE_TEST_PUBLIC_LIBRARIES} +absl_cc_test( + NAME + inline_variable_test + SRCS + "internal/inline_variable_testing.h" + "inline_variable_test.cc" + "inline_variable_test_a.cc" + "inline_variable_test_b.cc" + DEPS + absl::base_internal + gtest_main ) - -# test invoke_test -set(INVOKE_TEST_SRC "invoke_test.cc") -set(INVOKE_TEST_PUBLIC_LIBRARIES absl::strings) - -absl_test( - TARGET +absl_cc_test( + NAME invoke_test - SOURCES - ${INVOKE_TEST_SRC} - PUBLIC_LIBRARIES - ${INVOKE_TEST_PUBLIC_LIBRARIES} -) - - -# test inline_variable_test -list(APPEND INLINE_VARIABLE_TEST_SRC - "internal/inline_variable_testing.h" - "inline_variable_test.cc" - "inline_variable_test_a.cc" - "inline_variable_test_b.cc" -) - -set(INLINE_VARIABLE_TEST_PUBLIC_LIBRARIES absl::base) - -absl_test( - TARGET - inline_variable_test - SOURCES - ${INLINE_VARIABLE_TEST_SRC} - PUBLIC_LIBRARIES - ${INLINE_VARIABLE_TEST_PUBLIC_LIBRARIES} + SRCS + "invoke_test.cc" + DEPS + absl::base_internal + absl::memory + absl::strings + gmock + gtest_main ) - -# test spinlock_test_common -set(SPINLOCK_TEST_COMMON_SRC "spinlock_test_common.cc") -set(SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET +absl_cc_library( + NAME spinlock_test_common - SOURCES - ${SPINLOCK_TEST_COMMON_SRC} - PUBLIC_LIBRARIES - ${SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES} + SRCS + "spinlock_test_common.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::base + absl::core_headers + absl::spinlock_wait + absl::synchronization + gtest + PUBLIC ) - -# test spinlock_test -set(SPINLOCK_TEST_SRC "spinlock_test_common.cc") -set(SPINLOCK_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET +# On bazel BUILD this target use "alwayslink = 1" which is not implemented here +absl_cc_test( + NAME spinlock_test - SOURCES - ${SPINLOCK_TEST_SRC} - PUBLIC_LIBRARIES - ${SPINLOCK_TEST_PUBLIC_LIBRARIES} + SRCS + "spinlock_test_common.cc" + DEPS + absl::base + absl::core_headers + absl::spinlock_wait + absl::synchronization + gtest_main ) +absl_cc_library( + NAME + endian + HDRS + "internal/endian.h" + "internal/unaligned_access.h" + DEPS + absl::config + absl::core_headers + PUBLIC +) -# test endian_test -set(ENDIAN_TEST_SRC "internal/endian_test.cc") - -absl_test( - TARGET +absl_cc_test( + NAME endian_test - SOURCES - ${ENDIAN_TEST_SRC} + SRCS + "internal/endian_test.cc" + DEPS + absl::base + absl::config + absl::endian + gtest_main ) - -# test config_test -set(CONFIG_TEST_SRC "config_test.cc") -set(CONFIG_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) -absl_test( - TARGET +absl_cc_test( + NAME config_test - SOURCES - ${CONFIG_TEST_SRC} - PUBLIC_LIBRARIES - ${CONFIG_TEST_PUBLIC_LIBRARIES} + SRCS + "config_test.cc" + DEPS + absl::config + absl::synchronization + gtest_main ) +absl_cc_test( + NAME + call_once_test + SRCS + "call_once_test.cc" + DEPS + absl::base + absl::core_headers + absl::synchronization + gtest_main +) -# test raw_logging_test -set(RAW_LOGGING_TEST_SRC "raw_logging_test.cc") -set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base absl::strings) - -absl_test( - TARGET +absl_cc_test( + NAME raw_logging_test - SOURCES - ${RAW_LOGGING_TEST_SRC} - PUBLIC_LIBRARIES - ${RAW_LOGGING_TEST_PUBLIC_LIBRARIES} + SRCS + "raw_logging_test.cc" + DEPS + absl::base + absl::strings + gtest_main ) - -# test sysinfo_test -set(SYSINFO_TEST_SRC "internal/sysinfo_test.cc") -set(SYSINFO_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET +absl_cc_test( + NAME sysinfo_test - SOURCES - ${SYSINFO_TEST_SRC} - PUBLIC_LIBRARIES - ${SYSINFO_TEST_PUBLIC_LIBRARIES} + SRCS + "internal/sysinfo_test.cc" + DEPS + absl::base + absl::synchronization + gtest_main ) - -# test low_level_alloc_test -set(LOW_LEVEL_ALLOC_TEST_SRC "internal/low_level_alloc_test.cc") -set(LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES absl::base) - -absl_test( - TARGET +absl_cc_test( + NAME low_level_alloc_test - SOURCES - ${LOW_LEVEL_ALLOC_TEST_SRC} - PUBLIC_LIBRARIES - ${LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES} + SRCS + "internal/low_level_alloc_test.cc" + DEPS + absl::malloc_internal + Threads::Threads ) - -# test thread_identity_test -set(THREAD_IDENTITY_TEST_SRC "internal/thread_identity_test.cc") -set(THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) - -absl_test( - TARGET +absl_cc_test( + NAME thread_identity_test - SOURCES - ${THREAD_IDENTITY_TEST_SRC} - PUBLIC_LIBRARIES - ${THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES} + SRCS + "internal/thread_identity_test.cc" + DEPS + absl::base + absl::core_headers + absl::synchronization + Threads::Threads + gtest_main ) -#test exceptions_safety_testing_test -set(EXCEPTION_SAFETY_TESTING_TEST_SRC "exception_safety_testing_test.cc") -set(EXCEPTION_SAFETY_TESTING_TEST_PUBLIC_LIBRARIES - absl::base - absl_internal_exception_safety_testing - absl::memory - absl::meta - absl::strings - absl::utility +absl_cc_library( + NAME + bits + HDRS + "internal/bits.h" + DEPS + absl::core_headers ) -absl_test( - TARGET - absl_exception_safety_testing_test - SOURCES - ${EXCEPTION_SAFETY_TESTING_TEST_SRC} - PUBLIC_LIBRARIES - ${EXCEPTION_SAFETY_TESTING_TEST_PUBLIC_LIBRARIES} - PRIVATE_COMPILE_FLAGS - ${ABSL_EXCEPTIONS_FLAG} +absl_cc_test( + NAME + bits_test + SRCS + "internal/bits_test.cc" + DEPS + absl::bits + gtest_main ) diff --git a/absl/base/config.h b/absl/base/config.h index ca089f6d..db4c4539 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -365,6 +365,18 @@ #error "absl endian detection needs to be set up for your compiler" #endif +// MacOS 10.13 doesn't let you use , , or even though +// the headers exist and are publicly noted to work. See +// https://github.com/abseil/abseil-cpp/issues/207 and +// https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes +#if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \ + defined(__MAC_OS_X_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 +#define ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES 1 +#else +#define ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES 0 +#endif + // ABSL_HAVE_STD_ANY // // Checks whether C++17 std::any is available by checking whether exists. @@ -373,7 +385,8 @@ #endif #ifdef __has_include -#if __has_include() && __cplusplus >= 201703L +#if __has_include() && __cplusplus >= 201703L && \ + ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES #define ABSL_HAVE_STD_ANY 1 #endif #endif @@ -386,7 +399,8 @@ #endif #ifdef __has_include -#if __has_include() && __cplusplus >= 201703L +#if __has_include() && __cplusplus >= 201703L && \ + ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES #define ABSL_HAVE_STD_OPTIONAL 1 #endif #endif @@ -399,7 +413,8 @@ #endif #ifdef __has_include -#if __has_include() && __cplusplus >= 201703L +#if __has_include() && __cplusplus >= 201703L && \ + ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES #define ABSL_HAVE_STD_VARIANT 1 #endif #endif diff --git a/absl/base/internal/throw_delegate.cc b/absl/base/internal/throw_delegate.cc index 46dc573c..1c40efcb 100644 --- a/absl/base/internal/throw_delegate.cc +++ b/absl/base/internal/throw_delegate.cc @@ -30,8 +30,8 @@ template #ifdef ABSL_HAVE_EXCEPTIONS throw error; #else - ABSL_RAW_LOG(ERROR, "%s", error.what()); - abort(); + ABSL_RAW_LOG(FATAL, "%s", error.what()); + std::abort(); #endif } } // namespace diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index 9d92e15c..76aba318 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -14,7 +14,6 @@ #include "absl/container/internal/raw_hash_set.h" -#include #include #include #include @@ -1782,143 +1781,6 @@ TEST(Table, IterationOrderChangesForSmallTables) { FAIL() << "Iteration order remained the same across many attempts."; } -// Fill the table to 3 different load factors (min, median, max) and evaluate -// the percentage of perfect hits using the debug API. -template -std::vector CollectPerfectRatios(Table, AddFn add) { - std::vector results(3); - - constexpr size_t kNumTrials = 10; - std::vector tables(kNumTrials); - - for (Table& t : tables) { - using Key = typename Table::key_type; - - // First, fill enough to have a good distribution. - constexpr size_t kMinSize = 10000; - std::vector keys; - while (t.size() < kMinSize) keys.push_back(add(t)); - // Then, insert until we reach min load factor. - double lf = t.load_factor(); - while (lf <= t.load_factor()) keys.push_back(add(t)); - - // We are now at min load factor. Take a snapshot. - size_t perfect = 0; - auto update_perfect = [&](Key k) { - perfect += GetHashtableDebugNumProbes(t, k) == 0; - }; - for (const auto& k : keys) update_perfect(k); - - std::vector perfect_ratios; - // Keep going until we hit max load factor. - while (t.load_factor() < .6) { - perfect_ratios.push_back(1.0 * perfect / t.size()); - update_perfect(add(t)); - } - while (t.load_factor() > .5) { - perfect_ratios.push_back(1.0 * perfect / t.size()); - update_perfect(add(t)); - } - - results[0] += perfect_ratios.front(); - results[1] += perfect_ratios[perfect_ratios.size() / 2]; - results[2] += perfect_ratios.back(); - } - - results[0] /= kNumTrials; - results[1] /= kNumTrials; - results[2] /= kNumTrials; - - return results; -} - -std::vector> StringTablePefectRatios() { - constexpr bool kRandomizesInserts = -#if NDEBUG - false; -#else // NDEBUG - true; -#endif // NDEBUG - - // The effective load factor is larger in non-opt mode because we insert - // elements out of order. - switch (container_internal::Group::kWidth) { - case 8: - if (kRandomizesInserts) { - return {{0.986, 0.02}, {0.95, 0.02}, {0.89, 0.02}}; - } else { - return {{0.995, 0.01}, {0.97, 0.01}, {0.89, 0.02}}; - } - case 16: - if (kRandomizesInserts) { - return {{0.973, 0.01}, {0.965, 0.01}, {0.92, 0.02}}; - } else { - return {{0.995, 0.005}, {0.99, 0.005}, {0.94, 0.01}}; - } - } - ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width"); - return {}; -} - -// This is almost a change detector, but it allows us to know how we are -// affecting the probe distribution. -TEST(Table, EffectiveLoadFactorStrings) { - std::vector perfect_ratios = - CollectPerfectRatios(StringTable(), [](StringTable& t) { - return t.emplace(std::to_string(t.size()), "").first->first; - }); - - auto ratios = StringTablePefectRatios(); - if (ratios.empty()) return; - EXPECT_THAT(perfect_ratios, - ElementsAre(DoubleNear(ratios[0].first, ratios[0].second), - DoubleNear(ratios[1].first, ratios[1].second), - DoubleNear(ratios[2].first, ratios[2].second))); -} - -std::vector> IntTablePefectRatios() { - constexpr bool kRandomizesInserts = -#ifdef NDEBUG - false; -#else // NDEBUG - true; -#endif // NDEBUG - - // The effective load factor is larger in non-opt mode because we insert - // elements out of order. - switch (container_internal::Group::kWidth) { - case 8: - if (kRandomizesInserts) { - return {{0.99, 0.02}, {0.985, 0.02}, {0.95, 0.05}}; - } else { - return {{0.99, 0.01}, {0.99, 0.01}, {0.95, 0.02}}; - } - case 16: - if (kRandomizesInserts) { - return {{0.98, 0.02}, {0.978, 0.02}, {0.96, 0.02}}; - } else { - return {{0.998, 0.003}, {0.995, 0.01}, {0.975, 0.02}}; - } - } - ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width"); - return {}; -} - -// This is almost a change detector, but it allows us to know how we are -// affecting the probe distribution. -TEST(Table, EffectiveLoadFactorInts) { - std::vector perfect_ratios = CollectPerfectRatios( - IntTable(), [](IntTable& t) { return *t.emplace(t.size()).first; }); - - auto ratios = IntTablePefectRatios(); - if (ratios.empty()) return; - - EXPECT_THAT(perfect_ratios, - ElementsAre(DoubleNear(ratios[0].first, ratios[0].second), - DoubleNear(ratios[1].first, ratios[1].second), - DoubleNear(ratios[2].first, ratios[2].second))); -} - // Confirm that we assert if we try to erase() end(). TEST(TableDeathTest, EraseOfEndAsserts) { // Use an assert with side-effects to figure out if they are actually enabled. diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index 266c2ca0..c28eb14b 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt @@ -85,7 +85,7 @@ absl_library( ${SYMBOLIZE_SRC} PUBLIC_LIBRARIES absl::base - absl_internal_malloc_internal + absl::malloc_internal EXPORT_NAME symbolize ) diff --git a/absl/time/internal/cctz/include/cctz/civil_time_detail.h b/absl/time/internal/cctz/include/cctz/civil_time_detail.h index 855958ec..0cf27ddb 100644 --- a/absl/time/internal/cctz/include/cctz/civil_time_detail.h +++ b/absl/time/internal/cctz/include/cctz/civil_time_detail.h @@ -326,6 +326,37 @@ CONSTEXPR_F fields align(year_tag, fields f) noexcept { //////////////////////////////////////////////////////////////////////// +namespace impl { + +template +H AbslHashValueImpl(second_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm, f.ss); +} +template +H AbslHashValueImpl(minute_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d, f.hh, f.mm); +} +template +H AbslHashValueImpl(hour_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d, f.hh); +} +template +H AbslHashValueImpl(day_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m, f.d); +} +template +H AbslHashValueImpl(month_tag, H h, fields f) { + return H::combine(std::move(h), f.y, f.m); +} +template +H AbslHashValueImpl(year_tag, H h, fields f) { + return H::combine(std::move(h), f.y); +} + +} // namespace impl + +//////////////////////////////////////////////////////////////////////// + template class civil_time { public: @@ -418,8 +449,7 @@ class civil_time { template friend H AbslHashValue(H h, civil_time a) { - return H::combine(std::move(h), a.f_.y, a.f_.m, a.f_.d, - a.f_.hh, a.f_.mm, a.f_.ss); + return impl::AbslHashValueImpl(T{}, std::move(h), a.f_); } private: -- cgit v1.2.3 From 419f3184f8ebcdb23105295eadd2a569f3351eb9 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 28 Feb 2019 09:21:10 -0800 Subject: Export of internal Abseil changes. -- 92e1bd6dc9e64163659028b640427d6d8573e41c by Abseil Team : Don't enable ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE with MSVC when used with nvcc. With nvcc on Windows __has_trivial_assign(int) is false; that leads to a failure of the check in is_trivially_copy_assignable. A better solution would probably be to use the std-provided check in this case, but that seems like a more intrusive change. PiperOrigin-RevId: 236135209 -- 26cee4a7e647076b4e2f88375b4848d1469e55ed by Derek Mauro : Remove hashtablez_force_sampling from the open-source release. This should not have been released. It is internal-only and not portable. Fixes https://github.com/abseil/abseil-cpp/issues/268 PiperOrigin-RevId: 235978666 -- 935a885ec0e108963014f1bb79f00102da8f3871 by CJ Johnson : Internal change PiperOrigin-RevId: 235976027 -- 1c148c89de6064031f1ad9f2eeac0331bd77b7b0 by Tom Manshreck : Add design note for absl::from_chars to abseil.io Fixes #165 PiperOrigin-RevId: 235975923 GitOrigin-RevId: 92e1bd6dc9e64163659028b640427d6d8573e41c Change-Id: I220b0bbb46742070ea8c2a94b06007ecae76fe0f --- absl/base/config.h | 4 +- absl/container/BUILD.bazel | 23 --------- absl/container/CMakeLists.txt | 24 --------- .../internal/hashtablez_force_sampling.cc | 24 --------- .../internal/hashtablez_force_sampling_test.cc | 60 ---------------------- absl/strings/charconv.cc | 7 +-- 6 files changed, 6 insertions(+), 136 deletions(-) delete mode 100644 absl/container/internal/hashtablez_force_sampling.cc delete mode 100644 absl/container/internal/hashtablez_force_sampling_test.cc (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index db4c4539..eb0d79df 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -118,7 +118,7 @@ // Checks whether `std::is_trivially_copy_assignable` is supported. // Notes: Clang with libc++ supports these features, as does gcc >= 5.1 with -// either libc++ or libstdc++, and Visual Studio. +// either libc++ or libstdc++, and Visual Studio (but not NVCC). #if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) #error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set #elif defined(ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE) @@ -127,7 +127,7 @@ (!defined(__clang__) && defined(__GNUC__) && \ (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)) && \ (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \ - defined(_MSC_VER) + (defined(_MSC_VER) && !defined(__NVCC__)) #define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 #define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 #endif diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index f3b3a2c0..91013e04 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -446,15 +446,6 @@ cc_library( copts = ABSL_DEFAULT_COPTS, ) -cc_library( - name = "hashtablez_force_sampling", - srcs = ["internal/hashtablez_force_sampling.cc"], - copts = ABSL_DEFAULT_COPTS, - deps = [ - ":hashtablez_sampler", - ], -) - cc_library( name = "hashtablez_sampler", srcs = [ @@ -488,20 +479,6 @@ cc_test( ], ) -cc_test( - name = "hashtablez_force_sampling_test", - srcs = ["internal/hashtablez_force_sampling_test.cc"], - tags = [ - "no_test_darwin_x86_64", - "no_test_msvc_x64", - ], - deps = [ - ":hashtablez_force_sampling", - ":hashtablez_sampler", - "@com_google_googletest//:gtest_main", - ], -) - cc_library( name = "node_hash_policy", hdrs = ["internal/node_hash_policy.h"], diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 822388bd..c6053d74 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -464,30 +464,6 @@ absl_cc_test( gmock_main ) -absl_cc_library( - NAME - hashtablez_force_sampling - SRCS - "internal/hashtablez_force_sampling.cc" - COPTS - ${ABSL_DEFAULT_COPTS} - DEPS - absl::base - absl::have_sse - absl::synchronization -) - -absl_cc_test( - NAME - hashtablez_force_sampling_test - SRCS - "internal/hashtablez_force_sampling_test.cc" - DEPS - absl::hashtablez_force_sampling - absl::hashtablez_sampler - gmock_main -) - absl_cc_library( NAME hashtable_debug diff --git a/absl/container/internal/hashtablez_force_sampling.cc b/absl/container/internal/hashtablez_force_sampling.cc deleted file mode 100644 index 868976ec..00000000 --- a/absl/container/internal/hashtablez_force_sampling.cc +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2018 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 -// -// http://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. - -#include "absl/container/internal/hashtablez_sampler.h" - -namespace absl { -namespace container_internal { - -// See hashtablez_sampler.h for details. -extern "C" const bool kAbslContainerInternalSampleEverything = true; - -} // namespace container_internal -} // namespace absl diff --git a/absl/container/internal/hashtablez_force_sampling_test.cc b/absl/container/internal/hashtablez_force_sampling_test.cc deleted file mode 100644 index 9ff1046a..00000000 --- a/absl/container/internal/hashtablez_force_sampling_test.cc +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2018 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 -// -// http://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. - -#include - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "absl/container/internal/hashtablez_sampler.h" - -namespace absl { -namespace container_internal { - -class HashtablezInfoHandlePeer { - public: - static bool IsSampled(const HashtablezInfoHandle& h) { - return h.info_ != nullptr; - } -}; - -namespace { - -bool samples[3]{true, true, true}; - -// We do this test in a global object to test that this works even before main. -struct Global { - Global() { - // By default it is sampled. - samples[0] = HashtablezInfoHandlePeer::IsSampled(Sample()); - - // Even with a large parameter, it is sampled. - SetHashtablezSampleParameter(100); - samples[1] = HashtablezInfoHandlePeer::IsSampled(Sample()); - - // Even if we turn it off, it is still sampled. - SetHashtablezEnabled(false); - samples[2] = HashtablezInfoHandlePeer::IsSampled(Sample()); - } -} global; - -TEST(kAbslContainerInternalSampleEverything, Works) { - EXPECT_THAT(samples, testing::Each(true)); - EXPECT_TRUE(kAbslContainerInternalSampleEverything); - // One more after main() - EXPECT_TRUE(HashtablezInfoHandlePeer::IsSampled(Sample())); -} - -} // namespace -} // namespace container_internal -} // namespace absl diff --git a/absl/strings/charconv.cc b/absl/strings/charconv.cc index c7b8c98b..d0aa1913 100644 --- a/absl/strings/charconv.cc +++ b/absl/strings/charconv.cc @@ -551,9 +551,10 @@ CalculatedFloat CalculateFromParsedDecimal( int binary_exponent = Power10Exponent(parsed_decimal.exponent); // Discard bits that are inaccurate due to truncation error. The magic - // `mantissa_width` constants below are justified in charconv_algorithm.md. - // They represent the number of bits in `wide_binary_mantissa` that are - // guaranteed to be unaffected by error propagation. + // `mantissa_width` constants below are justified in + // https://abseil.io/about/design/charconv. They represent the number of bits + // in `wide_binary_mantissa` that are guaranteed to be unaffected by error + // propagation. bool mantissa_exact; int mantissa_width; if (parsed_decimal.subrange_begin) { -- cgit v1.2.3 From 9fdf5e5b805412cb2a2e624d3e9a11588120465f Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 4 Mar 2019 18:05:37 -0800 Subject: Export of internal Abseil changes. -- 425305bdac5c84a2b7b61d65aee90e4d9d1c29a0 by Abseil Team : Change a comment about hex strings to use lowercase 'a' and 'f' characters, since StrCat(Hex()) produces lowercase hex characters. PiperOrigin-RevId: 236763001 -- 2a312da1c2e46da3bdece0c322c4cd37356bb9aa by Samuel Benzaquen : Enable more tests for non-std containers by default. Add more tests for typedefs and other members. PiperOrigin-RevId: 236652269 -- 5d5abd4d8e8e03d3c924675550a9584325b18732 by Eric Fiselier : Fix incorrect detection of unavailable C++17 types. Using on OS X has complications, because it is present but marked "unavailable" due to dylib compatibility reasons. The dance we did to detect availability was correct on OS X, but accidentally clobbered all other platforms for not being Apple. This patch corrects the detection. PiperOrigin-RevId: 236651217 GitOrigin-RevId: 425305bdac5c84a2b7b61d65aee90e4d9d1c29a0 Change-Id: Ib922ce003422781aec169ea169d8fb15292ccd85 --- absl/base/config.h | 12 +- absl/container/BUILD.bazel | 34 ++++- absl/container/CMakeLists.txt | 36 ++++- absl/container/flat_hash_map_test.cc | 6 +- absl/container/flat_hash_set_test.cc | 2 + .../internal/unordered_map_constructor_test.h | 140 ++++++++++++++++---- .../internal/unordered_map_members_test.h | 85 ++++++++++++ absl/container/internal/unordered_map_test.cc | 2 + .../internal/unordered_set_constructor_test.h | 147 ++++++++++++++++----- .../internal/unordered_set_members_test.h | 84 ++++++++++++ absl/container/internal/unordered_set_test.cc | 2 + absl/container/node_hash_map_test.cc | 2 + absl/container/node_hash_set_test.cc | 4 +- absl/strings/str_cat.h | 4 +- 14 files changed, 482 insertions(+), 78 deletions(-) create mode 100644 absl/container/internal/unordered_map_members_test.h create mode 100644 absl/container/internal/unordered_set_members_test.h (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index eb0d79df..e2ef5e4c 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -371,10 +371,10 @@ // https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes #if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \ defined(__MAC_OS_X_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101400 -#define ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES 1 + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400 +#define ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE 1 #else -#define ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES 0 +#define ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE 0 #endif // ABSL_HAVE_STD_ANY @@ -386,7 +386,7 @@ #ifdef __has_include #if __has_include() && __cplusplus >= 201703L && \ - ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES + !ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE #define ABSL_HAVE_STD_ANY 1 #endif #endif @@ -400,7 +400,7 @@ #ifdef __has_include #if __has_include() && __cplusplus >= 201703L && \ - ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES + !ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE #define ABSL_HAVE_STD_OPTIONAL 1 #endif #endif @@ -414,7 +414,7 @@ #ifdef __has_include #if __has_include() && __cplusplus >= 201703L && \ - ABSL_INTERNAL_MACOS_HAS_CXX_17_TYPES + !ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE #define ABSL_HAVE_STD_VARIANT 1 #endif #endif diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 91013e04..04b4f9af 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -232,13 +232,14 @@ cc_library( cc_test( name = "flat_hash_map_test", srcs = ["flat_hash_map_test.cc"], - copts = ABSL_TEST_COPTS + ["-DUNORDERED_MAP_CXX17"], + copts = ABSL_TEST_COPTS, tags = NOTEST_TAGS_NONMOBILE, deps = [ ":flat_hash_map", ":hash_generator_testing", ":unordered_map_constructor_test", ":unordered_map_lookup_test", + ":unordered_map_members_test", ":unordered_map_modifiers_test", "//absl/types:any", "@com_google_googletest//:gtest_main", @@ -269,6 +270,7 @@ cc_test( ":hash_generator_testing", ":unordered_set_constructor_test", ":unordered_set_lookup_test", + ":unordered_set_members_test", ":unordered_set_modifiers_test", "//absl/memory", "//absl/strings", @@ -293,7 +295,7 @@ cc_library( cc_test( name = "node_hash_map_test", srcs = ["node_hash_map_test.cc"], - copts = ABSL_TEST_COPTS + ["-DUNORDERED_MAP_CXX17"], + copts = ABSL_TEST_COPTS, tags = NOTEST_TAGS_NONMOBILE, deps = [ ":hash_generator_testing", @@ -301,6 +303,7 @@ cc_test( ":tracked", ":unordered_map_constructor_test", ":unordered_map_lookup_test", + ":unordered_map_members_test", ":unordered_map_modifiers_test", "@com_google_googletest//:gtest_main", ], @@ -325,10 +328,10 @@ cc_test( copts = ABSL_TEST_COPTS + ["-DUNORDERED_SET_CXX17"], tags = NOTEST_TAGS_NONMOBILE, deps = [ - ":hash_generator_testing", ":node_hash_set", ":unordered_set_constructor_test", ":unordered_set_lookup_test", + ":unordered_set_members_test", ":unordered_set_modifiers_test", "@com_google_googletest//:gtest_main", ], @@ -659,6 +662,29 @@ cc_library( deps = [ ":hash_generator_testing", ":hash_policy_testing", + "//absl/meta:type_traits", + "@com_google_googletest//:gtest", + ], +) + +cc_library( + name = "unordered_set_members_test", + testonly = 1, + hdrs = ["internal/unordered_set_members_test.h"], + copts = ABSL_TEST_COPTS, + deps = [ + "//absl/meta:type_traits", + "@com_google_googletest//:gtest", + ], +) + +cc_library( + name = "unordered_map_members_test", + testonly = 1, + hdrs = ["internal/unordered_map_members_test.h"], + copts = ABSL_TEST_COPTS, + deps = [ + "//absl/meta:type_traits", "@com_google_googletest//:gtest", ], ) @@ -695,6 +721,7 @@ cc_test( deps = [ ":unordered_set_constructor_test", ":unordered_set_lookup_test", + ":unordered_set_members_test", ":unordered_set_modifiers_test", "@com_google_googletest//:gtest_main", ], @@ -708,6 +735,7 @@ cc_test( deps = [ ":unordered_map_constructor_test", ":unordered_map_lookup_test", + ":unordered_map_members_test", ":unordered_map_modifiers_test", "@com_google_googletest//:gtest_main", ], diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index c6053d74..56ea4294 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -213,13 +213,12 @@ absl_cc_test( flat_hash_map_test SRCS "flat_hash_map_test.cc" - COPTS - "-DUNORDERED_MAP_CXX17" DEPS absl::flat_hash_map absl::hash_generator_testing absl::unordered_map_constructor_test absl::unordered_map_lookup_test + absl::unordered_map_members_test absl::unordered_map_modifiers_test absl::any gmock_main @@ -254,6 +253,7 @@ absl_cc_test( absl::hash_generator_testing absl::unordered_set_constructor_test absl::unordered_set_lookup_test + absl::unordered_set_members_test absl::unordered_set_modifiers_test absl::memory absl::strings @@ -282,14 +282,13 @@ absl_cc_test( node_hash_map_test SRCS "node_hash_map_test.cc" - COPTS - "-DUNORDERED_MAP_CXX17" DEPS absl::hash_generator_testing absl::node_hash_map absl::tracked absl::unordered_map_constructor_test absl::unordered_map_lookup_test + absl::unordered_map_members_test absl::unordered_map_modifiers_test gmock_main ) @@ -322,6 +321,7 @@ absl_cc_test( absl::node_hash_set absl::unordered_set_constructor_test absl::unordered_set_lookup_test + absl::unordered_set_members_test absl::unordered_set_modifiers_test gmock_main ) @@ -664,6 +664,19 @@ absl_cc_library( TESTONLY ) +absl_cc_library( + NAME + unordered_map_members_test + HDRS + "internal/unordered_map_members_test.h" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::type_traits + gmock + TESTONLY +) + absl_cc_library( NAME unordered_map_modifiers_test @@ -706,6 +719,19 @@ absl_cc_library( TESTONLY ) +absl_cc_library( + NAME + unordered_set_members_test + HDRS + "internal/unordered_set_members_test.h" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::type_traits + gmock + TESTONLY +) + absl_cc_library( NAME unordered_set_modifiers_test @@ -728,6 +754,7 @@ absl_cc_test( DEPS absl::unordered_set_constructor_test absl::unordered_set_lookup_test + absl::unordered_set_members_test absl::unordered_set_modifiers_test gmock_main ) @@ -740,6 +767,7 @@ absl_cc_test( DEPS absl::unordered_map_constructor_test absl::unordered_map_lookup_test + absl::unordered_map_members_test absl::unordered_map_modifiers_test gmock_main ) diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc index ccc055f7..84ec9d56 100644 --- a/absl/container/flat_hash_map_test.cc +++ b/absl/container/flat_hash_map_test.cc @@ -17,6 +17,7 @@ #include "absl/container/internal/hash_generator_testing.h" #include "absl/container/internal/unordered_map_constructor_test.h" #include "absl/container/internal/unordered_map_lookup_test.h" +#include "absl/container/internal/unordered_map_members_test.h" #include "absl/container/internal/unordered_map_modifiers_test.h" #include "absl/types/any.h" @@ -30,8 +31,8 @@ using ::testing::Pair; using ::testing::UnorderedElementsAre; template -using Map = - flat_hash_map>; +using Map = flat_hash_map>>; static_assert(!std::is_standard_layout(), ""); @@ -42,6 +43,7 @@ using MapTypes = INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashMap, ConstructorTest, MapTypes); INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashMap, LookupTest, MapTypes); +INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashMap, MembersTest, MapTypes); INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashMap, ModifiersTest, MapTypes); TEST(FlatHashMap, StandardLayout) { diff --git a/absl/container/flat_hash_set_test.cc b/absl/container/flat_hash_set_test.cc index afbe7748..ae159a24 100644 --- a/absl/container/flat_hash_set_test.cc +++ b/absl/container/flat_hash_set_test.cc @@ -19,6 +19,7 @@ #include "absl/container/internal/hash_generator_testing.h" #include "absl/container/internal/unordered_set_constructor_test.h" #include "absl/container/internal/unordered_set_lookup_test.h" +#include "absl/container/internal/unordered_set_members_test.h" #include "absl/container/internal/unordered_set_modifiers_test.h" #include "absl/memory/memory.h" #include "absl/strings/string_view.h" @@ -42,6 +43,7 @@ using SetTypes = INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashSet, ConstructorTest, SetTypes); INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashSet, LookupTest, SetTypes); +INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashSet, MembersTest, SetTypes); INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashSet, ModifiersTest, SetTypes); TEST(FlatHashSet, EmplaceString) { diff --git a/absl/container/internal/unordered_map_constructor_test.h b/absl/container/internal/unordered_map_constructor_test.h index e70c191a..837d2317 100644 --- a/absl/container/internal/unordered_map_constructor_test.h +++ b/absl/container/internal/unordered_map_constructor_test.h @@ -83,8 +83,28 @@ TYPED_TEST_P(ConstructorTest, BucketCountHashEqualAlloc) { EXPECT_GE(m.bucket_count(), 123); } -TYPED_TEST_P(ConstructorTest, BucketCountAlloc) { +template +struct is_std_unordered_map : std::false_type {}; + +template +struct is_std_unordered_map> : std::true_type {}; + #if defined(UNORDERED_MAP_CXX14) || defined(UNORDERED_MAP_CXX17) +using has_cxx14_std_apis = std::true_type; +#else +using has_cxx14_std_apis = std::false_type; +#endif + +template +using expect_cxx14_apis = + absl::disjunction>, + has_cxx14_std_apis>; + +template +void BucketCountAllocTest(std::false_type) {} + +template +void BucketCountAllocTest(std::true_type) { using A = typename TypeParam::allocator_type; A alloc(0); TypeParam m(123, alloc); @@ -92,11 +112,17 @@ TYPED_TEST_P(ConstructorTest, BucketCountAlloc) { EXPECT_TRUE(m.empty()); EXPECT_THAT(m, ::testing::UnorderedElementsAre()); EXPECT_GE(m.bucket_count(), 123); -#endif } -TYPED_TEST_P(ConstructorTest, BucketCountHashAlloc) { -#if defined(UNORDERED_MAP_CXX14) || defined(UNORDERED_MAP_CXX17) +TYPED_TEST_P(ConstructorTest, BucketCountAlloc) { + BucketCountAllocTest(expect_cxx14_apis()); +} + +template +void BucketCountHashAllocTest(std::false_type) {} + +template +void BucketCountHashAllocTest(std::true_type) { using H = typename TypeParam::hasher; using A = typename TypeParam::allocator_type; H hasher; @@ -107,18 +133,38 @@ TYPED_TEST_P(ConstructorTest, BucketCountHashAlloc) { EXPECT_TRUE(m.empty()); EXPECT_THAT(m, ::testing::UnorderedElementsAre()); EXPECT_GE(m.bucket_count(), 123); -#endif } -TYPED_TEST_P(ConstructorTest, BucketAlloc) { +TYPED_TEST_P(ConstructorTest, BucketCountHashAlloc) { + BucketCountHashAllocTest(expect_cxx14_apis()); +} + #if ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS +using has_alloc_std_constructors = std::true_type; +#else +using has_alloc_std_constructors = std::false_type; +#endif + +template +using expect_alloc_constructors = + absl::disjunction>, + has_alloc_std_constructors>; + +template +void AllocTest(std::false_type) {} + +template +void AllocTest(std::true_type) { using A = typename TypeParam::allocator_type; A alloc(0); TypeParam m(alloc); EXPECT_EQ(m.get_allocator(), alloc); EXPECT_TRUE(m.empty()); EXPECT_THAT(m, ::testing::UnorderedElementsAre()); -#endif +} + +TYPED_TEST_P(ConstructorTest, Alloc) { + AllocTest(expect_alloc_constructors()); } TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashEqualAlloc) { @@ -140,8 +186,11 @@ TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashEqualAlloc) { EXPECT_GE(m.bucket_count(), 123); } -TYPED_TEST_P(ConstructorTest, InputIteratorBucketAlloc) { -#if defined(UNORDERED_MAP_CXX14) || defined(UNORDERED_MAP_CXX17) +template +void InputIteratorBucketAllocTest(std::false_type) {} + +template +void InputIteratorBucketAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using A = typename TypeParam::allocator_type; A alloc(0); @@ -152,11 +201,17 @@ TYPED_TEST_P(ConstructorTest, InputIteratorBucketAlloc) { EXPECT_EQ(m.get_allocator(), alloc); EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values)); EXPECT_GE(m.bucket_count(), 123); -#endif } -TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashAlloc) { -#if defined(UNORDERED_MAP_CXX14) || defined(UNORDERED_MAP_CXX17) +TYPED_TEST_P(ConstructorTest, InputIteratorBucketAlloc) { + InputIteratorBucketAllocTest(expect_cxx14_apis()); +} + +template +void InputIteratorBucketHashAllocTest(std::false_type) {} + +template +void InputIteratorBucketHashAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using H = typename TypeParam::hasher; using A = typename TypeParam::allocator_type; @@ -170,7 +225,10 @@ TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashAlloc) { EXPECT_EQ(m.get_allocator(), alloc); EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values)); EXPECT_GE(m.bucket_count(), 123); -#endif +} + +TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashAlloc) { + InputIteratorBucketHashAllocTest(expect_cxx14_apis()); } TYPED_TEST_P(ConstructorTest, CopyConstructor) { @@ -190,8 +248,11 @@ TYPED_TEST_P(ConstructorTest, CopyConstructor) { EXPECT_EQ(m, n); } -TYPED_TEST_P(ConstructorTest, CopyConstructorAlloc) { -#if ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS +template +void CopyConstructorAllocTest(std::false_type) {} + +template +void CopyConstructorAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using H = typename TypeParam::hasher; using E = typename TypeParam::key_equal; @@ -206,7 +267,10 @@ TYPED_TEST_P(ConstructorTest, CopyConstructorAlloc) { EXPECT_EQ(m.key_eq(), n.key_eq()); EXPECT_NE(m.get_allocator(), n.get_allocator()); EXPECT_EQ(m, n); -#endif +} + +TYPED_TEST_P(ConstructorTest, CopyConstructorAlloc) { + CopyConstructorAllocTest(expect_alloc_constructors()); } // TODO(alkis): Test non-propagating allocators on copy constructors. @@ -229,8 +293,11 @@ TYPED_TEST_P(ConstructorTest, MoveConstructor) { EXPECT_EQ(m, n); } -TYPED_TEST_P(ConstructorTest, MoveConstructorAlloc) { -#if ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS +template +void MoveConstructorAllocTest(std::false_type) {} + +template +void MoveConstructorAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using H = typename TypeParam::hasher; using E = typename TypeParam::key_equal; @@ -246,7 +313,10 @@ TYPED_TEST_P(ConstructorTest, MoveConstructorAlloc) { EXPECT_EQ(m.key_eq(), n.key_eq()); EXPECT_NE(m.get_allocator(), n.get_allocator()); EXPECT_EQ(m, n); -#endif +} + +TYPED_TEST_P(ConstructorTest, MoveConstructorAlloc) { + MoveConstructorAllocTest(expect_alloc_constructors()); } // TODO(alkis): Test non-propagating allocators on move constructors. @@ -269,8 +339,11 @@ TYPED_TEST_P(ConstructorTest, InitializerListBucketHashEqualAlloc) { EXPECT_GE(m.bucket_count(), 123); } -TYPED_TEST_P(ConstructorTest, InitializerListBucketAlloc) { -#if defined(UNORDERED_MAP_CXX14) || defined(UNORDERED_MAP_CXX17) +template +void InitializerListBucketAllocTest(std::false_type) {} + +template +void InitializerListBucketAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using A = typename TypeParam::allocator_type; hash_internal::Generator gen; @@ -280,11 +353,17 @@ TYPED_TEST_P(ConstructorTest, InitializerListBucketAlloc) { EXPECT_EQ(m.get_allocator(), alloc); EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values)); EXPECT_GE(m.bucket_count(), 123); -#endif } -TYPED_TEST_P(ConstructorTest, InitializerListBucketHashAlloc) { -#if defined(UNORDERED_MAP_CXX14) || defined(UNORDERED_MAP_CXX17) +TYPED_TEST_P(ConstructorTest, InitializerListBucketAlloc) { + InitializerListBucketAllocTest(expect_cxx14_apis()); +} + +template +void InitializerListBucketHashAllocTest(std::false_type) {} + +template +void InitializerListBucketHashAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using H = typename TypeParam::hasher; using A = typename TypeParam::allocator_type; @@ -297,7 +376,10 @@ TYPED_TEST_P(ConstructorTest, InitializerListBucketHashAlloc) { EXPECT_EQ(m.get_allocator(), alloc); EXPECT_THAT(items(m), ::testing::UnorderedElementsAreArray(values)); EXPECT_GE(m.bucket_count(), 123); -#endif +} + +TYPED_TEST_P(ConstructorTest, InitializerListBucketHashAlloc) { + InitializerListBucketHashAllocTest(expect_cxx14_apis()); } TYPED_TEST_P(ConstructorTest, Assignment) { @@ -390,13 +472,13 @@ TYPED_TEST_P(ConstructorTest, AssignmentOnSelf) { REGISTER_TYPED_TEST_CASE_P( ConstructorTest, NoArgs, BucketCount, BucketCountHash, BucketCountHashEqual, - BucketCountHashEqualAlloc, BucketCountAlloc, BucketCountHashAlloc, - BucketAlloc, InputIteratorBucketHashEqualAlloc, InputIteratorBucketAlloc, + BucketCountHashEqualAlloc, BucketCountAlloc, BucketCountHashAlloc, Alloc, + InputIteratorBucketHashEqualAlloc, InputIteratorBucketAlloc, InputIteratorBucketHashAlloc, CopyConstructor, CopyConstructorAlloc, MoveConstructor, MoveConstructorAlloc, InitializerListBucketHashEqualAlloc, InitializerListBucketAlloc, InitializerListBucketHashAlloc, Assignment, - MoveAssignment, AssignmentFromInitializerList, - AssignmentOverwritesExisting, MoveAssignmentOverwritesExisting, + MoveAssignment, AssignmentFromInitializerList, AssignmentOverwritesExisting, + MoveAssignmentOverwritesExisting, AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf); } // namespace container_internal diff --git a/absl/container/internal/unordered_map_members_test.h b/absl/container/internal/unordered_map_members_test.h new file mode 100644 index 00000000..5c9a799c --- /dev/null +++ b/absl/container/internal/unordered_map_members_test.h @@ -0,0 +1,85 @@ +// 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 +// +// http://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. + +#ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MEMBERS_TEST_H_ +#define ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MEMBERS_TEST_H_ + +#include +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/meta/type_traits.h" + +namespace absl { +namespace container_internal { + +template +class MembersTest : public ::testing::Test {}; + +TYPED_TEST_SUITE_P(MembersTest); + +template +void UseType() {} + +TYPED_TEST_P(MembersTest, Typedefs) { + EXPECT_TRUE((std::is_same, + typename TypeParam::value_type>())); + EXPECT_TRUE((absl::conjunction< + absl::negation>, + std::is_integral>())); + EXPECT_TRUE((absl::conjunction< + std::is_signed, + std::is_integral>())); + EXPECT_TRUE((std::is_convertible< + decltype(std::declval()( + std::declval())), + size_t>())); + EXPECT_TRUE((std::is_convertible< + decltype(std::declval()( + std::declval(), + std::declval())), + bool>())); + EXPECT_TRUE((std::is_same())); + EXPECT_TRUE((std::is_same())); + EXPECT_TRUE((std::is_same())); + EXPECT_TRUE((std::is_same::pointer, + typename TypeParam::pointer>())); + EXPECT_TRUE( + (std::is_same::const_pointer, + typename TypeParam::const_pointer>())); +} + +TYPED_TEST_P(MembersTest, SimpleFunctions) { + EXPECT_GT(TypeParam().max_size(), 0); +} + +TYPED_TEST_P(MembersTest, BeginEnd) { + TypeParam t = {typename TypeParam::value_type{}}; + EXPECT_EQ(t.begin(), t.cbegin()); + EXPECT_EQ(t.end(), t.cend()); + EXPECT_NE(t.begin(), t.end()); + EXPECT_NE(t.cbegin(), t.cend()); +} + +REGISTER_TYPED_TEST_SUITE_P(MembersTest, Typedefs, SimpleFunctions, BeginEnd); + +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_UNORDERED_MAP_MEMBERS_TEST_H_ diff --git a/absl/container/internal/unordered_map_test.cc b/absl/container/internal/unordered_map_test.cc index 2752cb76..32ab48d0 100644 --- a/absl/container/internal/unordered_map_test.cc +++ b/absl/container/internal/unordered_map_test.cc @@ -16,6 +16,7 @@ #include "absl/container/internal/unordered_map_constructor_test.h" #include "absl/container/internal/unordered_map_lookup_test.h" +#include "absl/container/internal/unordered_map_members_test.h" #include "absl/container/internal/unordered_map_modifiers_test.h" namespace absl { @@ -31,6 +32,7 @@ using MapTypes = ::testing::Types< INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedMap, ConstructorTest, MapTypes); INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedMap, LookupTest, MapTypes); +INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedMap, MembersTest, MapTypes); INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedMap, ModifiersTest, MapTypes); } // namespace diff --git a/absl/container/internal/unordered_set_constructor_test.h b/absl/container/internal/unordered_set_constructor_test.h index 8997046a..533a6217 100644 --- a/absl/container/internal/unordered_set_constructor_test.h +++ b/absl/container/internal/unordered_set_constructor_test.h @@ -16,12 +16,14 @@ #define ABSL_CONTAINER_INTERNAL_UNORDERED_SET_CONSTRUCTOR_TEST_H_ #include +#include #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/container/internal/hash_generator_testing.h" #include "absl/container/internal/hash_policy_testing.h" +#include "absl/meta/type_traits.h" namespace absl { namespace container_internal { @@ -91,8 +93,28 @@ TYPED_TEST_P(ConstructorTest, BucketCountHashEqualAlloc) { EXPECT_GE(cm.bucket_count(), 123); } -TYPED_TEST_P(ConstructorTest, BucketCountAlloc) { +template +struct is_std_unordered_set : std::false_type {}; + +template +struct is_std_unordered_set> : std::true_type {}; + #if defined(UNORDERED_SET_CXX14) || defined(UNORDERED_SET_CXX17) +using has_cxx14_std_apis = std::true_type; +#else +using has_cxx14_std_apis = std::false_type; +#endif + +template +using expect_cxx14_apis = + absl::disjunction>, + has_cxx14_std_apis>; + +template +void BucketCountAllocTest(std::false_type) {} + +template +void BucketCountAllocTest(std::true_type) { using A = typename TypeParam::allocator_type; A alloc(0); TypeParam m(123, alloc); @@ -100,11 +122,17 @@ TYPED_TEST_P(ConstructorTest, BucketCountAlloc) { EXPECT_TRUE(m.empty()); EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre()); EXPECT_GE(m.bucket_count(), 123); -#endif } -TYPED_TEST_P(ConstructorTest, BucketCountHashAlloc) { -#if defined(UNORDERED_SET_CXX14) || defined(UNORDERED_SET_CXX17) +TYPED_TEST_P(ConstructorTest, BucketCountAlloc) { + BucketCountAllocTest(expect_cxx14_apis()); +} + +template +void BucketCountHashAllocTest(std::false_type) {} + +template +void BucketCountHashAllocTest(std::true_type) { using H = typename TypeParam::hasher; using A = typename TypeParam::allocator_type; H hasher; @@ -115,18 +143,38 @@ TYPED_TEST_P(ConstructorTest, BucketCountHashAlloc) { EXPECT_TRUE(m.empty()); EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre()); EXPECT_GE(m.bucket_count(), 123); -#endif } -TYPED_TEST_P(ConstructorTest, BucketAlloc) { +TYPED_TEST_P(ConstructorTest, BucketCountHashAlloc) { + BucketCountHashAllocTest(expect_cxx14_apis()); +} + #if ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS +using has_alloc_std_constructors = std::true_type; +#else +using has_alloc_std_constructors = std::false_type; +#endif + +template +using expect_alloc_constructors = + absl::disjunction>, + has_alloc_std_constructors>; + +template +void AllocTest(std::false_type) {} + +template +void AllocTest(std::true_type) { using A = typename TypeParam::allocator_type; A alloc(0); TypeParam m(alloc); EXPECT_EQ(m.get_allocator(), alloc); EXPECT_TRUE(m.empty()); EXPECT_THAT(keys(m), ::testing::UnorderedElementsAre()); -#endif +} + +TYPED_TEST_P(ConstructorTest, Alloc) { + AllocTest(expect_alloc_constructors()); } TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashEqualAlloc) { @@ -148,8 +196,11 @@ TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashEqualAlloc) { EXPECT_GE(m.bucket_count(), 123); } -TYPED_TEST_P(ConstructorTest, InputIteratorBucketAlloc) { -#if defined(UNORDERED_SET_CXX14) || defined(UNORDERED_SET_CXX17) +template +void InputIteratorBucketAllocTest(std::false_type) {} + +template +void InputIteratorBucketAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using A = typename TypeParam::allocator_type; A alloc(0); @@ -160,11 +211,17 @@ TYPED_TEST_P(ConstructorTest, InputIteratorBucketAlloc) { EXPECT_EQ(m.get_allocator(), alloc); EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values)); EXPECT_GE(m.bucket_count(), 123); -#endif } -TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashAlloc) { -#if defined(UNORDERED_SET_CXX14) || defined(UNORDERED_SET_CXX17) +TYPED_TEST_P(ConstructorTest, InputIteratorBucketAlloc) { + InputIteratorBucketAllocTest(expect_cxx14_apis()); +} + +template +void InputIteratorBucketHashAllocTest(std::false_type) {} + +template +void InputIteratorBucketHashAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using H = typename TypeParam::hasher; using A = typename TypeParam::allocator_type; @@ -178,7 +235,10 @@ TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashAlloc) { EXPECT_EQ(m.get_allocator(), alloc); EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values)); EXPECT_GE(m.bucket_count(), 123); -#endif +} + +TYPED_TEST_P(ConstructorTest, InputIteratorBucketHashAlloc) { + InputIteratorBucketHashAllocTest(expect_cxx14_apis()); } TYPED_TEST_P(ConstructorTest, CopyConstructor) { @@ -196,10 +256,14 @@ TYPED_TEST_P(ConstructorTest, CopyConstructor) { EXPECT_EQ(m.key_eq(), n.key_eq()); EXPECT_EQ(m.get_allocator(), n.get_allocator()); EXPECT_EQ(m, n); + EXPECT_NE(TypeParam(0, hasher, equal, alloc), n); } -TYPED_TEST_P(ConstructorTest, CopyConstructorAlloc) { -#if ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS +template +void CopyConstructorAllocTest(std::false_type) {} + +template +void CopyConstructorAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using H = typename TypeParam::hasher; using E = typename TypeParam::key_equal; @@ -214,7 +278,10 @@ TYPED_TEST_P(ConstructorTest, CopyConstructorAlloc) { EXPECT_EQ(m.key_eq(), n.key_eq()); EXPECT_NE(m.get_allocator(), n.get_allocator()); EXPECT_EQ(m, n); -#endif +} + +TYPED_TEST_P(ConstructorTest, CopyConstructorAlloc) { + CopyConstructorAllocTest(expect_alloc_constructors()); } // TODO(alkis): Test non-propagating allocators on copy constructors. @@ -237,8 +304,11 @@ TYPED_TEST_P(ConstructorTest, MoveConstructor) { EXPECT_EQ(m, n); } -TYPED_TEST_P(ConstructorTest, MoveConstructorAlloc) { -#if ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS +template +void MoveConstructorAllocTest(std::false_type) {} + +template +void MoveConstructorAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using H = typename TypeParam::hasher; using E = typename TypeParam::key_equal; @@ -254,7 +324,10 @@ TYPED_TEST_P(ConstructorTest, MoveConstructorAlloc) { EXPECT_EQ(m.key_eq(), n.key_eq()); EXPECT_NE(m.get_allocator(), n.get_allocator()); EXPECT_EQ(m, n); -#endif +} + +TYPED_TEST_P(ConstructorTest, MoveConstructorAlloc) { + MoveConstructorAllocTest(expect_alloc_constructors()); } // TODO(alkis): Test non-propagating allocators on move constructors. @@ -277,8 +350,11 @@ TYPED_TEST_P(ConstructorTest, InitializerListBucketHashEqualAlloc) { EXPECT_GE(m.bucket_count(), 123); } -TYPED_TEST_P(ConstructorTest, InitializerListBucketAlloc) { -#if defined(UNORDERED_SET_CXX14) || defined(UNORDERED_SET_CXX17) +template +void InitializerListBucketAllocTest(std::false_type) {} + +template +void InitializerListBucketAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using A = typename TypeParam::allocator_type; hash_internal::Generator gen; @@ -288,11 +364,17 @@ TYPED_TEST_P(ConstructorTest, InitializerListBucketAlloc) { EXPECT_EQ(m.get_allocator(), alloc); EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values)); EXPECT_GE(m.bucket_count(), 123); -#endif } -TYPED_TEST_P(ConstructorTest, InitializerListBucketHashAlloc) { -#if defined(UNORDERED_SET_CXX14) || defined(UNORDERED_SET_CXX17) +TYPED_TEST_P(ConstructorTest, InitializerListBucketAlloc) { + InitializerListBucketAllocTest(expect_cxx14_apis()); +} + +template +void InitializerListBucketHashAllocTest(std::false_type) {} + +template +void InitializerListBucketHashAllocTest(std::true_type) { using T = hash_internal::GeneratedType; using H = typename TypeParam::hasher; using A = typename TypeParam::allocator_type; @@ -305,10 +387,13 @@ TYPED_TEST_P(ConstructorTest, InitializerListBucketHashAlloc) { EXPECT_EQ(m.get_allocator(), alloc); EXPECT_THAT(keys(m), ::testing::UnorderedElementsAreArray(values)); EXPECT_GE(m.bucket_count(), 123); -#endif } -TYPED_TEST_P(ConstructorTest, Assignment) { +TYPED_TEST_P(ConstructorTest, InitializerListBucketHashAlloc) { + InitializerListBucketHashAllocTest(expect_cxx14_apis()); +} + +TYPED_TEST_P(ConstructorTest, CopyAssignment) { using T = hash_internal::GeneratedType; using H = typename TypeParam::hasher; using E = typename TypeParam::key_equal; @@ -394,13 +479,13 @@ TYPED_TEST_P(ConstructorTest, AssignmentOnSelf) { REGISTER_TYPED_TEST_CASE_P( ConstructorTest, NoArgs, BucketCount, BucketCountHash, BucketCountHashEqual, - BucketCountHashEqualAlloc, BucketCountAlloc, BucketCountHashAlloc, - BucketAlloc, InputIteratorBucketHashEqualAlloc, InputIteratorBucketAlloc, + BucketCountHashEqualAlloc, BucketCountAlloc, BucketCountHashAlloc, Alloc, + InputIteratorBucketHashEqualAlloc, InputIteratorBucketAlloc, InputIteratorBucketHashAlloc, CopyConstructor, CopyConstructorAlloc, MoveConstructor, MoveConstructorAlloc, InitializerListBucketHashEqualAlloc, - InitializerListBucketAlloc, InitializerListBucketHashAlloc, Assignment, - MoveAssignment, AssignmentFromInitializerList, - AssignmentOverwritesExisting, MoveAssignmentOverwritesExisting, + InitializerListBucketAlloc, InitializerListBucketHashAlloc, CopyAssignment, + MoveAssignment, AssignmentFromInitializerList, AssignmentOverwritesExisting, + MoveAssignmentOverwritesExisting, AssignmentFromInitializerListOverwritesExisting, AssignmentOnSelf); } // namespace container_internal diff --git a/absl/container/internal/unordered_set_members_test.h b/absl/container/internal/unordered_set_members_test.h new file mode 100644 index 00000000..eaf00445 --- /dev/null +++ b/absl/container/internal/unordered_set_members_test.h @@ -0,0 +1,84 @@ +// 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 +// +// http://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. + +#ifndef ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MEMBERS_TEST_H_ +#define ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MEMBERS_TEST_H_ + +#include +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/meta/type_traits.h" + +namespace absl { +namespace container_internal { + +template +class MembersTest : public ::testing::Test {}; + +TYPED_TEST_SUITE_P(MembersTest); + +template +void UseType() {} + +TYPED_TEST_P(MembersTest, Typedefs) { + EXPECT_TRUE((std::is_same())); + EXPECT_TRUE((absl::conjunction< + absl::negation>, + std::is_integral>())); + EXPECT_TRUE((absl::conjunction< + std::is_signed, + std::is_integral>())); + EXPECT_TRUE((std::is_convertible< + decltype(std::declval()( + std::declval())), + size_t>())); + EXPECT_TRUE((std::is_convertible< + decltype(std::declval()( + std::declval(), + std::declval())), + bool>())); + EXPECT_TRUE((std::is_same())); + EXPECT_TRUE((std::is_same())); + EXPECT_TRUE((std::is_same())); + EXPECT_TRUE((std::is_same::pointer, + typename TypeParam::pointer>())); + EXPECT_TRUE( + (std::is_same::const_pointer, + typename TypeParam::const_pointer>())); +} + +TYPED_TEST_P(MembersTest, SimpleFunctions) { + EXPECT_GT(TypeParam().max_size(), 0); +} + +TYPED_TEST_P(MembersTest, BeginEnd) { + TypeParam t = {typename TypeParam::value_type{}}; + EXPECT_EQ(t.begin(), t.cbegin()); + EXPECT_EQ(t.end(), t.cend()); + EXPECT_NE(t.begin(), t.end()); + EXPECT_NE(t.cbegin(), t.cend()); +} + +REGISTER_TYPED_TEST_SUITE_P(MembersTest, Typedefs, SimpleFunctions, BeginEnd); + +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_UNORDERED_SET_MEMBERS_TEST_H_ diff --git a/absl/container/internal/unordered_set_test.cc b/absl/container/internal/unordered_set_test.cc index 04533bf0..d5a8613e 100644 --- a/absl/container/internal/unordered_set_test.cc +++ b/absl/container/internal/unordered_set_test.cc @@ -16,6 +16,7 @@ #include "absl/container/internal/unordered_set_constructor_test.h" #include "absl/container/internal/unordered_set_lookup_test.h" +#include "absl/container/internal/unordered_set_members_test.h" #include "absl/container/internal/unordered_set_modifiers_test.h" namespace absl { @@ -30,6 +31,7 @@ using SetTypes = INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedSet, ConstructorTest, SetTypes); INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedSet, LookupTest, SetTypes); +INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedSet, MembersTest, SetTypes); INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedSet, ModifiersTest, SetTypes); } // namespace diff --git a/absl/container/node_hash_map_test.cc b/absl/container/node_hash_map_test.cc index 87ea4560..87fd4185 100644 --- a/absl/container/node_hash_map_test.cc +++ b/absl/container/node_hash_map_test.cc @@ -17,6 +17,7 @@ #include "absl/container/internal/tracked.h" #include "absl/container/internal/unordered_map_constructor_test.h" #include "absl/container/internal/unordered_map_lookup_test.h" +#include "absl/container/internal/unordered_map_members_test.h" #include "absl/container/internal/unordered_map_modifiers_test.h" namespace absl { @@ -36,6 +37,7 @@ using MapTypes = ::testing::Types< INSTANTIATE_TYPED_TEST_SUITE_P(NodeHashMap, ConstructorTest, MapTypes); INSTANTIATE_TYPED_TEST_SUITE_P(NodeHashMap, LookupTest, MapTypes); +INSTANTIATE_TYPED_TEST_SUITE_P(NodeHashMap, MembersTest, MapTypes); INSTANTIATE_TYPED_TEST_SUITE_P(NodeHashMap, ModifiersTest, MapTypes); using M = absl::node_hash_map>; diff --git a/absl/container/node_hash_set_test.cc b/absl/container/node_hash_set_test.cc index 09cb7a98..5eaac2a5 100644 --- a/absl/container/node_hash_set_test.cc +++ b/absl/container/node_hash_set_test.cc @@ -16,6 +16,7 @@ #include "absl/container/internal/unordered_set_constructor_test.h" #include "absl/container/internal/unordered_set_lookup_test.h" +#include "absl/container/internal/unordered_set_members_test.h" #include "absl/container/internal/unordered_set_modifiers_test.h" namespace absl { @@ -29,13 +30,14 @@ using ::testing::UnorderedElementsAre; using SetTypes = ::testing::Types< node_hash_set>, node_hash_set>, + Alloc>, node_hash_set>, node_hash_set>>; INSTANTIATE_TYPED_TEST_SUITE_P(NodeHashSet, ConstructorTest, SetTypes); INSTANTIATE_TYPED_TEST_SUITE_P(NodeHashSet, LookupTest, SetTypes); +INSTANTIATE_TYPED_TEST_SUITE_P(NodeHashSet, MembersTest, SetTypes); INSTANTIATE_TYPED_TEST_SUITE_P(NodeHashSet, ModifiersTest, SetTypes); TEST(NodeHashSet, MoveableNotCopyableCompiles) { diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h index 8ba0592f..f4f4aca8 100644 --- a/absl/strings/str_cat.h +++ b/absl/strings/str_cat.h @@ -78,8 +78,8 @@ struct AlphaNumBuffer { // Enum that specifies the number of significant digits to return in a `Hex` or // `Dec` conversion and fill character to use. A `kZeroPad2` value, for example, -// would produce hexadecimal strings such as "0A","0F" and a 'kSpacePad5' value -// would produce hexadecimal strings such as " A"," F". +// would produce hexadecimal strings such as "0a","0f" and a 'kSpacePad5' value +// would produce hexadecimal strings such as " a"," f". enum PadSpec : uint8_t { kNoPad = 1, kZeroPad2, -- cgit v1.2.3 From 38b704384cd2f17590b3922b97744be0b43622c9 Mon Sep 17 00:00:00 2001 From: nik7273 Date: Fri, 8 Mar 2019 10:27:53 -0500 Subject: Changed HTTP URLs to HTTPS where possible (#270) --- CMake/AbseilHelpers.cmake | 2 +- CMake/README.md | 2 +- CMakeLists.txt | 2 +- LICENSE | 4 ++-- README.md | 8 ++++---- absl/BUILD.bazel | 2 +- absl/CMakeLists.txt | 2 +- absl/algorithm/BUILD.bazel | 2 +- absl/algorithm/CMakeLists.txt | 2 +- absl/algorithm/algorithm.h | 4 ++-- absl/algorithm/algorithm_test.cc | 2 +- absl/algorithm/container.h | 2 +- absl/algorithm/container_test.cc | 2 +- absl/algorithm/equal_benchmark.cc | 2 +- absl/base/BUILD.bazel | 2 +- absl/base/CMakeLists.txt | 2 +- absl/base/attributes.h | 2 +- absl/base/bit_cast_test.cc | 2 +- absl/base/call_once.h | 2 +- absl/base/call_once_test.cc | 2 +- absl/base/casts.h | 2 +- absl/base/config.h | 2 +- absl/base/config_test.cc | 2 +- absl/base/const_init.h | 2 +- absl/base/dynamic_annotations.cc | 2 +- absl/base/dynamic_annotations.h | 2 +- absl/base/exception_safety_testing_test.cc | 2 +- absl/base/inline_variable_test.cc | 2 +- absl/base/inline_variable_test_a.cc | 2 +- absl/base/inline_variable_test_b.cc | 2 +- absl/base/internal/atomic_hook.h | 2 +- absl/base/internal/atomic_hook_test.cc | 2 +- absl/base/internal/bits.h | 2 +- absl/base/internal/bits_test.cc | 2 +- absl/base/internal/cycleclock.cc | 2 +- absl/base/internal/cycleclock.h | 2 +- absl/base/internal/direct_mmap.h | 2 +- absl/base/internal/endian.h | 2 +- absl/base/internal/endian_test.cc | 2 +- absl/base/internal/exception_safety_testing.cc | 2 +- absl/base/internal/exception_safety_testing.h | 6 +++--- absl/base/internal/exception_testing.h | 2 +- absl/base/internal/hide_ptr.h | 2 +- absl/base/internal/identity.h | 2 +- absl/base/internal/inline_variable.h | 2 +- absl/base/internal/inline_variable_testing.h | 2 +- absl/base/internal/invoke.h | 2 +- absl/base/internal/low_level_alloc.cc | 2 +- absl/base/internal/low_level_alloc.h | 2 +- absl/base/internal/low_level_alloc_test.cc | 2 +- absl/base/internal/low_level_scheduling.h | 2 +- absl/base/internal/per_thread_tls.h | 2 +- absl/base/internal/pretty_function.h | 2 +- absl/base/internal/raw_logging.cc | 2 +- absl/base/internal/raw_logging.h | 2 +- absl/base/internal/scheduling_mode.h | 2 +- absl/base/internal/spinlock.cc | 2 +- absl/base/internal/spinlock.h | 2 +- absl/base/internal/spinlock_akaros.inc | 2 +- absl/base/internal/spinlock_benchmark.cc | 2 +- absl/base/internal/spinlock_linux.inc | 2 +- absl/base/internal/spinlock_posix.inc | 2 +- absl/base/internal/spinlock_wait.cc | 2 +- absl/base/internal/spinlock_wait.h | 2 +- absl/base/internal/spinlock_win32.inc | 2 +- absl/base/internal/sysinfo.cc | 2 +- absl/base/internal/sysinfo.h | 2 +- absl/base/internal/sysinfo_test.cc | 2 +- absl/base/internal/thread_identity.cc | 2 +- absl/base/internal/thread_identity.h | 2 +- absl/base/internal/thread_identity_benchmark.cc | 2 +- absl/base/internal/thread_identity_test.cc | 2 +- absl/base/internal/throw_delegate.cc | 2 +- absl/base/internal/throw_delegate.h | 2 +- absl/base/internal/tsan_mutex_interface.h | 2 +- absl/base/internal/unaligned_access.h | 2 +- absl/base/internal/unscaledcycleclock.cc | 2 +- absl/base/internal/unscaledcycleclock.h | 2 +- absl/base/invoke_test.cc | 2 +- absl/base/log_severity.h | 2 +- absl/base/macros.h | 2 +- absl/base/optimization.h | 2 +- absl/base/policy_checks.h | 2 +- absl/base/port.h | 2 +- absl/base/raw_logging_test.cc | 2 +- absl/base/spinlock_test_common.cc | 2 +- absl/base/thread_annotations.h | 2 +- absl/base/throw_delegate_test.cc | 2 +- absl/compiler_config_setting.bzl | 2 +- absl/container/BUILD.bazel | 2 +- absl/container/CMakeLists.txt | 2 +- absl/container/fixed_array.h | 2 +- absl/container/fixed_array_benchmark.cc | 2 +- absl/container/fixed_array_exception_safety_test.cc | 2 +- absl/container/fixed_array_test.cc | 2 +- absl/container/flat_hash_map.h | 2 +- absl/container/flat_hash_map_test.cc | 2 +- absl/container/flat_hash_set.h | 2 +- absl/container/flat_hash_set_test.cc | 2 +- absl/container/inlined_vector.h | 2 +- absl/container/inlined_vector_benchmark.cc | 2 +- absl/container/inlined_vector_test.cc | 2 +- absl/container/internal/common.h | 2 +- absl/container/internal/compressed_tuple.h | 6 +++--- absl/container/internal/compressed_tuple_test.cc | 2 +- absl/container/internal/container_memory.h | 2 +- absl/container/internal/container_memory_test.cc | 2 +- absl/container/internal/counting_allocator.h | 2 +- absl/container/internal/hash_function_defaults.h | 2 +- absl/container/internal/hash_function_defaults_test.cc | 2 +- absl/container/internal/hash_generator_testing.cc | 2 +- absl/container/internal/hash_generator_testing.h | 2 +- absl/container/internal/hash_policy_testing.h | 2 +- absl/container/internal/hash_policy_testing_test.cc | 2 +- absl/container/internal/hash_policy_traits.h | 2 +- absl/container/internal/hash_policy_traits_test.cc | 2 +- absl/container/internal/hashtable_debug.h | 2 +- absl/container/internal/hashtable_debug_hooks.h | 2 +- absl/container/internal/hashtablez_sampler.cc | 2 +- absl/container/internal/hashtablez_sampler.h | 2 +- .../internal/hashtablez_sampler_force_weak_definition.cc | 2 +- absl/container/internal/hashtablez_sampler_test.cc | 2 +- absl/container/internal/have_sse.h | 2 +- absl/container/internal/layout.h | 2 +- absl/container/internal/layout_test.cc | 2 +- absl/container/internal/node_hash_policy.h | 2 +- absl/container/internal/node_hash_policy_test.cc | 2 +- absl/container/internal/raw_hash_map.h | 2 +- absl/container/internal/raw_hash_set.cc | 2 +- absl/container/internal/raw_hash_set.h | 4 ++-- absl/container/internal/raw_hash_set_allocator_test.cc | 2 +- absl/container/internal/raw_hash_set_test.cc | 2 +- absl/container/internal/test_instance_tracker.cc | 2 +- absl/container/internal/test_instance_tracker.h | 2 +- absl/container/internal/test_instance_tracker_test.cc | 2 +- absl/container/internal/tracked.h | 2 +- absl/container/internal/unordered_map_constructor_test.h | 2 +- absl/container/internal/unordered_map_lookup_test.h | 2 +- absl/container/internal/unordered_map_modifiers_test.h | 2 +- absl/container/internal/unordered_map_test.cc | 2 +- absl/container/internal/unordered_set_constructor_test.h | 2 +- absl/container/internal/unordered_set_lookup_test.h | 2 +- absl/container/internal/unordered_set_modifiers_test.h | 2 +- absl/container/internal/unordered_set_test.cc | 2 +- absl/container/node_hash_map.h | 2 +- absl/container/node_hash_map_test.cc | 2 +- absl/container/node_hash_set.h | 2 +- absl/container/node_hash_set_test.cc | 2 +- absl/debugging/BUILD.bazel | 2 +- absl/debugging/CMakeLists.txt | 2 +- absl/debugging/failure_signal_handler.cc | 2 +- absl/debugging/failure_signal_handler.h | 2 +- absl/debugging/failure_signal_handler_test.cc | 2 +- absl/debugging/internal/address_is_readable.cc | 2 +- absl/debugging/internal/address_is_readable.h | 2 +- absl/debugging/internal/demangle.cc | 6 +++--- absl/debugging/internal/demangle.h | 2 +- absl/debugging/internal/demangle_test.cc | 2 +- absl/debugging/internal/elf_mem_image.cc | 2 +- absl/debugging/internal/elf_mem_image.h | 2 +- absl/debugging/internal/examine_stack.cc | 2 +- absl/debugging/internal/examine_stack.h | 2 +- absl/debugging/internal/stack_consumption.cc | 2 +- absl/debugging/internal/stack_consumption.h | 2 +- absl/debugging/internal/stack_consumption_test.cc | 2 +- absl/debugging/internal/stacktrace_config.h | 2 +- absl/debugging/internal/stacktrace_powerpc-inl.inc | 6 +++--- absl/debugging/internal/stacktrace_win32-inl.inc | 4 ++-- absl/debugging/internal/stacktrace_x86-inl.inc | 2 +- absl/debugging/internal/symbolize.h | 2 +- absl/debugging/internal/vdso_support.cc | 2 +- absl/debugging/internal/vdso_support.h | 2 +- absl/debugging/leak_check.cc | 2 +- absl/debugging/leak_check.h | 2 +- absl/debugging/leak_check_disable.cc | 2 +- absl/debugging/leak_check_fail_test.cc | 2 +- absl/debugging/leak_check_test.cc | 2 +- absl/debugging/stacktrace.cc | 2 +- absl/debugging/stacktrace.h | 2 +- absl/debugging/symbolize.cc | 2 +- absl/debugging/symbolize.h | 2 +- absl/debugging/symbolize_elf.inc | 2 +- absl/debugging/symbolize_test.cc | 2 +- absl/debugging/symbolize_unimplemented.inc | 2 +- absl/debugging/symbolize_win32.inc | 2 +- absl/hash/BUILD.bazel | 2 +- absl/hash/CMakeLists.txt | 2 +- absl/hash/hash.h | 2 +- absl/hash/hash_test.cc | 2 +- absl/hash/hash_testing.h | 2 +- absl/hash/internal/city.cc | 2 +- absl/hash/internal/city.h | 4 ++-- absl/hash/internal/city_test.cc | 2 +- absl/hash/internal/hash.cc | 2 +- absl/hash/internal/hash.h | 2 +- absl/hash/internal/print_hash_of.cc | 2 +- absl/hash/internal/spy_hash_state.h | 2 +- absl/memory/BUILD.bazel | 2 +- absl/memory/CMakeLists.txt | 2 +- absl/memory/memory.h | 4 ++-- absl/memory/memory_exception_safety_test.cc | 2 +- absl/memory/memory_test.cc | 2 +- absl/meta/CMakeLists.txt | 2 +- absl/meta/type_traits.h | 6 +++--- absl/meta/type_traits_test.cc | 2 +- absl/numeric/BUILD.bazel | 2 +- absl/numeric/CMakeLists.txt | 2 +- absl/numeric/int128.cc | 4 ++-- absl/numeric/int128.h | 2 +- absl/numeric/int128_benchmark.cc | 2 +- absl/numeric/int128_have_intrinsic.inc | 2 +- absl/numeric/int128_no_intrinsic.inc | 2 +- absl/numeric/int128_stream_test.cc | 2 +- absl/numeric/int128_test.cc | 2 +- absl/strings/BUILD.bazel | 2 +- absl/strings/CMakeLists.txt | 2 +- absl/strings/ascii.cc | 2 +- absl/strings/ascii.h | 2 +- absl/strings/ascii_benchmark.cc | 2 +- absl/strings/ascii_test.cc | 2 +- absl/strings/charconv.cc | 2 +- absl/strings/charconv.h | 2 +- absl/strings/charconv_benchmark.cc | 2 +- absl/strings/charconv_test.cc | 2 +- absl/strings/escaping.cc | 10 +++++----- absl/strings/escaping.h | 6 +++--- absl/strings/escaping_benchmark.cc | 2 +- absl/strings/escaping_test.cc | 2 +- absl/strings/internal/char_map.h | 2 +- absl/strings/internal/char_map_benchmark.cc | 2 +- absl/strings/internal/char_map_test.cc | 2 +- absl/strings/internal/charconv_bigint.cc | 2 +- absl/strings/internal/charconv_bigint.h | 2 +- absl/strings/internal/charconv_bigint_test.cc | 2 +- absl/strings/internal/charconv_parse.cc | 2 +- absl/strings/internal/charconv_parse.h | 2 +- absl/strings/internal/charconv_parse_test.cc | 2 +- absl/strings/internal/escaping_test_common.h | 2 +- absl/strings/internal/memutil.cc | 2 +- absl/strings/internal/memutil.h | 2 +- absl/strings/internal/memutil_benchmark.cc | 2 +- absl/strings/internal/memutil_test.cc | 2 +- absl/strings/internal/numbers_test_common.h | 2 +- absl/strings/internal/ostringstream.cc | 2 +- absl/strings/internal/ostringstream.h | 2 +- absl/strings/internal/ostringstream_benchmark.cc | 2 +- absl/strings/internal/ostringstream_test.cc | 2 +- absl/strings/internal/pow10_helper.cc | 2 +- absl/strings/internal/pow10_helper.h | 2 +- absl/strings/internal/pow10_helper_test.cc | 2 +- absl/strings/internal/resize_uninitialized.h | 2 +- absl/strings/internal/resize_uninitialized_test.cc | 2 +- absl/strings/internal/stl_type_traits.h | 2 +- absl/strings/internal/str_format/arg_test.cc | 2 +- absl/strings/internal/str_format/extension.cc | 2 +- absl/strings/internal/str_format/extension.h | 2 +- absl/strings/internal/str_format/extension_test.cc | 2 +- absl/strings/internal/str_format/output.cc | 2 +- absl/strings/internal/str_format/output.h | 2 +- absl/strings/internal/str_format/output_test.cc | 2 +- absl/strings/internal/str_join_internal.h | 2 +- absl/strings/internal/str_split_internal.h | 2 +- absl/strings/internal/utf8.cc | 2 +- absl/strings/internal/utf8.h | 2 +- absl/strings/internal/utf8_test.cc | 2 +- absl/strings/match.cc | 2 +- absl/strings/match.h | 2 +- absl/strings/match_test.cc | 2 +- absl/strings/numbers.cc | 2 +- absl/strings/numbers.h | 6 +++--- absl/strings/numbers_benchmark.cc | 2 +- absl/strings/numbers_test.cc | 2 +- absl/strings/str_cat.cc | 2 +- absl/strings/str_cat.h | 2 +- absl/strings/str_cat_benchmark.cc | 2 +- absl/strings/str_cat_test.cc | 2 +- absl/strings/str_format.h | 2 +- absl/strings/str_join.h | 2 +- absl/strings/str_join_benchmark.cc | 2 +- absl/strings/str_join_test.cc | 2 +- absl/strings/str_replace.cc | 2 +- absl/strings/str_replace.h | 2 +- absl/strings/str_replace_benchmark.cc | 2 +- absl/strings/str_replace_test.cc | 2 +- absl/strings/str_split.cc | 2 +- absl/strings/str_split.h | 2 +- absl/strings/str_split_benchmark.cc | 2 +- absl/strings/str_split_test.cc | 2 +- absl/strings/string_view.cc | 4 ++-- absl/strings/string_view.h | 2 +- absl/strings/string_view_benchmark.cc | 2 +- absl/strings/string_view_test.cc | 2 +- absl/strings/strip.h | 2 +- absl/strings/strip_test.cc | 2 +- absl/strings/substitute.cc | 2 +- absl/strings/substitute.h | 2 +- absl/strings/substitute_test.cc | 2 +- absl/synchronization/BUILD.bazel | 2 +- absl/synchronization/CMakeLists.txt | 2 +- absl/synchronization/barrier.cc | 2 +- absl/synchronization/barrier.h | 2 +- absl/synchronization/barrier_test.cc | 2 +- absl/synchronization/blocking_counter.cc | 2 +- absl/synchronization/blocking_counter.h | 2 +- absl/synchronization/blocking_counter_test.cc | 2 +- absl/synchronization/internal/create_thread_identity.cc | 2 +- absl/synchronization/internal/create_thread_identity.h | 2 +- absl/synchronization/internal/graphcycles.cc | 2 +- absl/synchronization/internal/graphcycles.h | 2 +- absl/synchronization/internal/graphcycles_benchmark.cc | 2 +- absl/synchronization/internal/graphcycles_test.cc | 2 +- absl/synchronization/internal/kernel_timeout.h | 2 +- absl/synchronization/internal/mutex_nonprod.cc | 2 +- absl/synchronization/internal/per_thread_sem.cc | 2 +- absl/synchronization/internal/per_thread_sem.h | 2 +- absl/synchronization/internal/per_thread_sem_test.cc | 2 +- absl/synchronization/internal/thread_pool.h | 2 +- absl/synchronization/internal/waiter.cc | 2 +- absl/synchronization/internal/waiter.h | 2 +- absl/synchronization/lifetime_test.cc | 2 +- absl/synchronization/mutex.cc | 2 +- absl/synchronization/mutex.h | 2 +- absl/synchronization/mutex_benchmark.cc | 2 +- absl/synchronization/mutex_test.cc | 2 +- absl/synchronization/notification.cc | 2 +- absl/synchronization/notification.h | 2 +- absl/synchronization/notification_test.cc | 2 +- absl/time/BUILD.bazel | 2 +- absl/time/CMakeLists.txt | 2 +- absl/time/civil_time.cc | 2 +- absl/time/civil_time.h | 2 +- absl/time/civil_time_benchmark.cc | 2 +- absl/time/civil_time_test.cc | 2 +- absl/time/clock.cc | 2 +- absl/time/clock.h | 2 +- absl/time/clock_benchmark.cc | 2 +- absl/time/clock_test.cc | 2 +- absl/time/duration.cc | 8 ++++---- absl/time/duration_benchmark.cc | 2 +- absl/time/duration_test.cc | 2 +- absl/time/format.cc | 2 +- absl/time/format_benchmark.cc | 2 +- absl/time/format_test.cc | 2 +- absl/time/internal/get_current_time_chrono.inc | 2 +- absl/time/internal/test_util.cc | 2 +- absl/time/internal/test_util.h | 2 +- absl/time/time.cc | 2 +- absl/time/time.h | 2 +- absl/time/time_benchmark.cc | 2 +- absl/time/time_test.cc | 2 +- absl/time/time_zone_test.cc | 2 +- absl/types/BUILD.bazel | 2 +- absl/types/CMakeLists.txt | 2 +- absl/types/any.h | 2 +- absl/types/any_exception_safety_test.cc | 2 +- absl/types/any_test.cc | 2 +- absl/types/bad_any_cast.cc | 2 +- absl/types/bad_any_cast.h | 2 +- absl/types/bad_optional_access.cc | 2 +- absl/types/bad_optional_access.h | 2 +- absl/types/bad_variant_access.cc | 2 +- absl/types/bad_variant_access.h | 2 +- absl/types/internal/variant.h | 2 +- absl/types/optional.cc | 2 +- absl/types/optional.h | 2 +- absl/types/optional_exception_safety_test.cc | 2 +- absl/types/optional_test.cc | 2 +- absl/types/span.h | 2 +- absl/types/span_test.cc | 2 +- absl/types/variant.h | 2 +- absl/types/variant_benchmark.cc | 2 +- absl/types/variant_exception_safety_test.cc | 2 +- absl/types/variant_test.cc | 2 +- absl/utility/CMakeLists.txt | 2 +- absl/utility/utility.h | 6 +++--- absl/utility/utility_test.cc | 2 +- 376 files changed, 410 insertions(+), 410 deletions(-) (limited to 'absl/base/config.h') diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake index 49ef7dcc..7c81beaf 100644 --- a/CMake/AbseilHelpers.cmake +++ b/CMake/AbseilHelpers.cmake @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/CMake/README.md b/CMake/README.md index 66c37692..02359d36 100644 --- a/CMake/README.md +++ b/CMake/README.md @@ -3,7 +3,7 @@ Abseil comes with a CMake build script ([CMakeLists.txt](../CMakeLists.txt)) that can be used on a wide range of platforms ("C" stands for cross-platform.). If you don't have CMake installed already, you can download it for free from -. +. CMake works by generating native makefiles or build projects that can be used in the compiler environment of your choice. diff --git a/CMakeLists.txt b/CMakeLists.txt index 380ed74f..a56d238b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/LICENSE b/LICENSE index 6b0b1270..ccd61dcf 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/ + https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -193,7 +193,7 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + 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, diff --git a/README.md b/README.md index e9362be2..2c513ea6 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ the Abseil code, running tests, and getting a simple binary working. ## Building Abseil -[Bazel](http://bazel.build) is the official build system for Abseil, +[Bazel](https://bazel.build) is the official build system for Abseil, which is supported on most major platforms (Linux, Windows, MacOS, for example) and compilers. See the [quickstart](https://abseil.io/docs/cpp/quickstart) for more information on building Abseil using the Bazel build system. @@ -106,9 +106,9 @@ license. See [LICENSE](LICENSE) for more information. For more information about Abseil: -* Consult our [Abseil Introduction](http://abseil.io/about/intro) -* Read [Why Adopt Abseil](http://abseil.io/about/philosophy) to understand our +* Consult our [Abseil Introduction](https://abseil.io/about/intro) +* Read [Why Adopt Abseil](https://abseil.io/about/philosophy) to understand our design philosophy. * Peruse our - [Abseil Compatibility Guarantees](http://abseil.io/about/compatibility) to + [Abseil Compatibility Guarantees](https://abseil.io/about/compatibility) to understand both what we promise to you, and what we expect of you in return. diff --git a/absl/BUILD.bazel b/absl/BUILD.bazel index edd0274c..8e3c1773 100644 --- a/absl/BUILD.bazel +++ b/absl/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/CMakeLists.txt b/absl/CMakeLists.txt index 1d09b193..bba0f3e7 100644 --- a/absl/CMakeLists.txt +++ b/absl/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/algorithm/BUILD.bazel b/absl/algorithm/BUILD.bazel index 4314ee86..8d266db5 100644 --- a/absl/algorithm/BUILD.bazel +++ b/absl/algorithm/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/algorithm/CMakeLists.txt b/absl/algorithm/CMakeLists.txt index 87a165c0..c51eb10e 100644 --- a/absl/algorithm/CMakeLists.txt +++ b/absl/algorithm/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/algorithm/algorithm.h b/absl/algorithm/algorithm.h index 3d658643..bb90215d 100644 --- a/absl/algorithm/algorithm.h +++ b/absl/algorithm/algorithm.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -94,7 +94,7 @@ It RotateImpl(It first, It middle, It last, std::false_type) { // then the predicate is never invoked and the function returns false. // // This is a C++11-compatible implementation of C++14 `std::equal`. See -// http://en.cppreference.com/w/cpp/algorithm/equal for more information. +// https://en.cppreference.com/w/cpp/algorithm/equal for more information. template bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2, Pred&& pred) { diff --git a/absl/algorithm/algorithm_test.cc b/absl/algorithm/algorithm_test.cc index e4322bc4..81fccb61 100644 --- a/absl/algorithm/algorithm_test.cc +++ b/absl/algorithm/algorithm_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h index 6d5f6630..7348d632 100644 --- a/absl/algorithm/container.h +++ b/absl/algorithm/container.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/algorithm/container_test.cc b/absl/algorithm/container_test.cc index 1502b17f..04282b89 100644 --- a/absl/algorithm/container_test.cc +++ b/absl/algorithm/container_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/algorithm/equal_benchmark.cc b/absl/algorithm/equal_benchmark.cc index 19c0780c..7bf62c9a 100644 --- a/absl/algorithm/equal_benchmark.cc +++ b/absl/algorithm/equal_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 49ae1824..12a8a130 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 1016a665..936c0d2d 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/base/attributes.h b/absl/base/attributes.h index fa44012e..dc3a95a4 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/bit_cast_test.cc b/absl/base/bit_cast_test.cc index 8cd878d7..4846add4 100644 --- a/absl/base/bit_cast_test.cc +++ b/absl/base/bit_cast_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/call_once.h b/absl/base/call_once.h index f6c8ebb2..8c4f297c 100644 --- a/absl/base/call_once.h +++ b/absl/base/call_once.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/call_once_test.cc b/absl/base/call_once_test.cc index 183b92ef..9c2a0c44 100644 --- a/absl/base/call_once_test.cc +++ b/absl/base/call_once_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/casts.h b/absl/base/casts.h index 1eef6a61..00196d20 100644 --- a/absl/base/casts.h +++ b/absl/base/casts.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/config.h b/absl/base/config.h index e2ef5e4c..3b81e269 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/config_test.cc b/absl/base/config_test.cc index c839712a..7e0c033d 100644 --- a/absl/base/config_test.cc +++ b/absl/base/config_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/const_init.h b/absl/base/const_init.h index fc88b267..1b2b8c2b 100644 --- a/absl/base/const_init.h +++ b/absl/base/const_init.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/dynamic_annotations.cc b/absl/base/dynamic_annotations.cc index 08c27e51..21e822e5 100644 --- a/absl/base/dynamic_annotations.cc +++ b/absl/base/dynamic_annotations.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/dynamic_annotations.h b/absl/base/dynamic_annotations.h index 7e328d96..cdeb18c2 100644 --- a/absl/base/dynamic_annotations.h +++ b/absl/base/dynamic_annotations.h @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/absl/base/exception_safety_testing_test.cc b/absl/base/exception_safety_testing_test.cc index 7518264d..2ed38606 100644 --- a/absl/base/exception_safety_testing_test.cc +++ b/absl/base/exception_safety_testing_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/inline_variable_test.cc b/absl/base/inline_variable_test.cc index 5499189a..471f7063 100644 --- a/absl/base/inline_variable_test.cc +++ b/absl/base/inline_variable_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/inline_variable_test_a.cc b/absl/base/inline_variable_test_a.cc index a3bf3b68..d0b8e7d3 100644 --- a/absl/base/inline_variable_test_a.cc +++ b/absl/base/inline_variable_test_a.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/inline_variable_test_b.cc b/absl/base/inline_variable_test_b.cc index b4b9393a..931d56d0 100644 --- a/absl/base/inline_variable_test_b.cc +++ b/absl/base/inline_variable_test_b.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/atomic_hook.h b/absl/base/internal/atomic_hook.h index b458511b..803e9059 100644 --- a/absl/base/internal/atomic_hook.h +++ b/absl/base/internal/atomic_hook.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/atomic_hook_test.cc b/absl/base/internal/atomic_hook_test.cc index cf740757..ecc80406 100644 --- a/absl/base/internal/atomic_hook_test.cc +++ b/absl/base/internal/atomic_hook_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/bits.h b/absl/base/internal/bits.h index bc7faaee..b0780f2d 100644 --- a/absl/base/internal/bits.h +++ b/absl/base/internal/bits.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/bits_test.cc b/absl/base/internal/bits_test.cc index e5d991d6..7855fa62 100644 --- a/absl/base/internal/bits_test.cc +++ b/absl/base/internal/bits_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/cycleclock.cc b/absl/base/internal/cycleclock.cc index 9eb13b8c..4b553c29 100644 --- a/absl/base/internal/cycleclock.cc +++ b/absl/base/internal/cycleclock.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/cycleclock.h b/absl/base/internal/cycleclock.h index 9853a66c..7874db71 100644 --- a/absl/base/internal/cycleclock.h +++ b/absl/base/internal/cycleclock.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/direct_mmap.h b/absl/base/internal/direct_mmap.h index 654a6007..0401ddfa 100644 --- a/absl/base/internal/direct_mmap.h +++ b/absl/base/internal/direct_mmap.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/endian.h b/absl/base/internal/endian.h index 3f59184a..6b828b6e 100644 --- a/absl/base/internal/endian.h +++ b/absl/base/internal/endian.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/endian_test.cc b/absl/base/internal/endian_test.cc index e2769155..98a099e4 100644 --- a/absl/base/internal/endian_test.cc +++ b/absl/base/internal/endian_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/exception_safety_testing.cc b/absl/base/internal/exception_safety_testing.cc index 8207b7d7..6ef4325c 100644 --- a/absl/base/internal/exception_safety_testing.cc +++ b/absl/base/internal/exception_safety_testing.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/exception_safety_testing.h b/absl/base/internal/exception_safety_testing.h index 07ce47d4..be38ba54 100644 --- a/absl/base/internal/exception_safety_testing.h +++ b/absl/base/internal/exception_safety_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -558,8 +558,8 @@ class ThrowingValue : private exceptions_internal::TrackedObject { // We provide both regular and templated operator delete because if only the // templated version is provided as we did with operator new, the compiler has // no way of knowing which overload of operator delete to call. See - // http://en.cppreference.com/w/cpp/memory/new/operator_delete and - // http://en.cppreference.com/w/cpp/language/delete for the gory details. + // https://en.cppreference.com/w/cpp/memory/new/operator_delete and + // https://en.cppreference.com/w/cpp/language/delete for the gory details. void operator delete(void* p) noexcept { ::operator delete(p); } template diff --git a/absl/base/internal/exception_testing.h b/absl/base/internal/exception_testing.h index 0cf7918e..01b54655 100644 --- a/absl/base/internal/exception_testing.h +++ b/absl/base/internal/exception_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/hide_ptr.h b/absl/base/internal/hide_ptr.h index 45cf4389..cf8f4080 100644 --- a/absl/base/internal/hide_ptr.h +++ b/absl/base/internal/hide_ptr.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/identity.h b/absl/base/internal/identity.h index a1a5d70a..086447c6 100644 --- a/absl/base/internal/identity.h +++ b/absl/base/internal/identity.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/inline_variable.h b/absl/base/internal/inline_variable.h index f7bb8c56..130d8c24 100644 --- a/absl/base/internal/inline_variable.h +++ b/absl/base/internal/inline_variable.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/inline_variable_testing.h b/absl/base/internal/inline_variable_testing.h index a0dd2bb2..15dc481e 100644 --- a/absl/base/internal/inline_variable_testing.h +++ b/absl/base/internal/inline_variable_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/invoke.h b/absl/base/internal/invoke.h index 8c3f4f60..8da2869a 100644 --- a/absl/base/internal/invoke.h +++ b/absl/base/internal/invoke.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/low_level_alloc.cc b/absl/base/internal/low_level_alloc.cc index 4af9c05d..5a8199e6 100644 --- a/absl/base/internal/low_level_alloc.cc +++ b/absl/base/internal/low_level_alloc.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/low_level_alloc.h b/absl/base/internal/low_level_alloc.h index fba9466a..f83c7bc8 100644 --- a/absl/base/internal/low_level_alloc.h +++ b/absl/base/internal/low_level_alloc.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/low_level_alloc_test.cc b/absl/base/internal/low_level_alloc_test.cc index cf2b3632..d2d31820 100644 --- a/absl/base/internal/low_level_alloc_test.cc +++ b/absl/base/internal/low_level_alloc_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/low_level_scheduling.h b/absl/base/internal/low_level_scheduling.h index e716f2b4..2a5a3847 100644 --- a/absl/base/internal/low_level_scheduling.h +++ b/absl/base/internal/low_level_scheduling.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/per_thread_tls.h b/absl/base/internal/per_thread_tls.h index 56359853..cf5e97a0 100644 --- a/absl/base/internal/per_thread_tls.h +++ b/absl/base/internal/per_thread_tls.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/pretty_function.h b/absl/base/internal/pretty_function.h index 01b0547b..35d51676 100644 --- a/absl/base/internal/pretty_function.h +++ b/absl/base/internal/pretty_function.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc index d9485a66..b5a05e8c 100644 --- a/absl/base/internal/raw_logging.cc +++ b/absl/base/internal/raw_logging.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h index f34e263e..4cbbbe59 100644 --- a/absl/base/internal/raw_logging.h +++ b/absl/base/internal/raw_logging.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/scheduling_mode.h b/absl/base/internal/scheduling_mode.h index 1b6497ad..d5b4b7fd 100644 --- a/absl/base/internal/scheduling_mode.h +++ b/absl/base/internal/scheduling_mode.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/spinlock.cc b/absl/base/internal/spinlock.cc index 28ba1af7..7354438f 100644 --- a/absl/base/internal/spinlock.cc +++ b/absl/base/internal/spinlock.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/spinlock.h b/absl/base/internal/spinlock.h index eb3eec9c..4a316399 100644 --- a/absl/base/internal/spinlock.h +++ b/absl/base/internal/spinlock.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/spinlock_akaros.inc b/absl/base/internal/spinlock_akaros.inc index 051c8cf8..bc468940 100644 --- a/absl/base/internal/spinlock_akaros.inc +++ b/absl/base/internal/spinlock_akaros.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/spinlock_benchmark.cc b/absl/base/internal/spinlock_benchmark.cc index 907d3e27..0451c65f 100644 --- a/absl/base/internal/spinlock_benchmark.cc +++ b/absl/base/internal/spinlock_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/spinlock_linux.inc b/absl/base/internal/spinlock_linux.inc index 3bbd4954..28e29d19 100644 --- a/absl/base/internal/spinlock_linux.inc +++ b/absl/base/internal/spinlock_linux.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/spinlock_posix.inc b/absl/base/internal/spinlock_posix.inc index 0098c1c7..f025b5f8 100644 --- a/absl/base/internal/spinlock_posix.inc +++ b/absl/base/internal/spinlock_posix.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/spinlock_wait.cc b/absl/base/internal/spinlock_wait.cc index 7e4f4352..fac8a21d 100644 --- a/absl/base/internal/spinlock_wait.cc +++ b/absl/base/internal/spinlock_wait.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/spinlock_wait.h b/absl/base/internal/spinlock_wait.h index 5c6cc7fd..6642ce1a 100644 --- a/absl/base/internal/spinlock_wait.h +++ b/absl/base/internal/spinlock_wait.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/spinlock_win32.inc b/absl/base/internal/spinlock_win32.inc index 32c8fc0b..78654b5b 100644 --- a/absl/base/internal/spinlock_win32.inc +++ b/absl/base/internal/spinlock_win32.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc index db41bacc..4dd3adda 100644 --- a/absl/base/internal/sysinfo.cc +++ b/absl/base/internal/sysinfo.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/sysinfo.h b/absl/base/internal/sysinfo.h index 5bd1c500..b864a597 100644 --- a/absl/base/internal/sysinfo.h +++ b/absl/base/internal/sysinfo.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/sysinfo_test.cc b/absl/base/internal/sysinfo_test.cc index e0d9aab9..247f3d88 100644 --- a/absl/base/internal/sysinfo_test.cc +++ b/absl/base/internal/sysinfo_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/thread_identity.cc b/absl/base/internal/thread_identity.cc index cff9c1b4..91273a6b 100644 --- a/absl/base/internal/thread_identity.cc +++ b/absl/base/internal/thread_identity.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/thread_identity.h b/absl/base/internal/thread_identity.h index 3b3b7b75..dde3e010 100644 --- a/absl/base/internal/thread_identity.h +++ b/absl/base/internal/thread_identity.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/thread_identity_benchmark.cc b/absl/base/internal/thread_identity_benchmark.cc index 242522b4..0ae10f2b 100644 --- a/absl/base/internal/thread_identity_benchmark.cc +++ b/absl/base/internal/thread_identity_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/thread_identity_test.cc b/absl/base/internal/thread_identity_test.cc index ecb8af68..13bfbe3b 100644 --- a/absl/base/internal/thread_identity_test.cc +++ b/absl/base/internal/thread_identity_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/throw_delegate.cc b/absl/base/internal/throw_delegate.cc index 1c40efcb..8e928b8a 100644 --- a/absl/base/internal/throw_delegate.cc +++ b/absl/base/internal/throw_delegate.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/throw_delegate.h b/absl/base/internal/throw_delegate.h index 70e2d770..03c700b5 100644 --- a/absl/base/internal/throw_delegate.h +++ b/absl/base/internal/throw_delegate.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/tsan_mutex_interface.h b/absl/base/internal/tsan_mutex_interface.h index 6bb4faed..2a510603 100644 --- a/absl/base/internal/tsan_mutex_interface.h +++ b/absl/base/internal/tsan_mutex_interface.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/unaligned_access.h b/absl/base/internal/unaligned_access.h index f9df3b78..2d667377 100644 --- a/absl/base/internal/unaligned_access.h +++ b/absl/base/internal/unaligned_access.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/unscaledcycleclock.cc b/absl/base/internal/unscaledcycleclock.cc index a12d68bd..593762bc 100644 --- a/absl/base/internal/unscaledcycleclock.cc +++ b/absl/base/internal/unscaledcycleclock.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/internal/unscaledcycleclock.h b/absl/base/internal/unscaledcycleclock.h index 049f1cac..d5e186a9 100644 --- a/absl/base/internal/unscaledcycleclock.h +++ b/absl/base/internal/unscaledcycleclock.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/invoke_test.cc b/absl/base/invoke_test.cc index 466bf114..691f5537 100644 --- a/absl/base/invoke_test.cc +++ b/absl/base/invoke_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/log_severity.h b/absl/base/log_severity.h index 5770d362..4b9833eb 100644 --- a/absl/base/log_severity.h +++ b/absl/base/log_severity.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/macros.h b/absl/base/macros.h index 5ed12cb0..5b43d7c2 100644 --- a/absl/base/macros.h +++ b/absl/base/macros.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/optimization.h b/absl/base/optimization.h index 9789c2cc..6974f1f6 100644 --- a/absl/base/optimization.h +++ b/absl/base/optimization.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/policy_checks.h b/absl/base/policy_checks.h index 0a07fc03..699fb1a2 100644 --- a/absl/base/policy_checks.h +++ b/absl/base/policy_checks.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/port.h b/absl/base/port.h index 1c67257f..6c28068d 100644 --- a/absl/base/port.h +++ b/absl/base/port.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/raw_logging_test.cc b/absl/base/raw_logging_test.cc index b21cf651..3d30bd38 100644 --- a/absl/base/raw_logging_test.cc +++ b/absl/base/raw_logging_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/spinlock_test_common.cc b/absl/base/spinlock_test_common.cc index 19170813..b32cea29 100644 --- a/absl/base/spinlock_test_common.cc +++ b/absl/base/spinlock_test_common.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/thread_annotations.h b/absl/base/thread_annotations.h index 2241ace4..a8162d41 100644 --- a/absl/base/thread_annotations.h +++ b/absl/base/thread_annotations.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/base/throw_delegate_test.cc b/absl/base/throw_delegate_test.cc index 0f15df04..a74dd3cd 100644 --- a/absl/base/throw_delegate_test.cc +++ b/absl/base/throw_delegate_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/compiler_config_setting.bzl b/absl/compiler_config_setting.bzl index b77c4f56..f1a87018 100644 --- a/absl/compiler_config_setting.bzl +++ b/absl/compiler_config_setting.bzl @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 04b4f9af..b6592ca5 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 56ea4294..76542be1 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h index 6da84411..0161d0a9 100644 --- a/absl/container/fixed_array.h +++ b/absl/container/fixed_array.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/fixed_array_benchmark.cc b/absl/container/fixed_array_benchmark.cc index b4f0cf2a..ff56f466 100644 --- a/absl/container/fixed_array_benchmark.cc +++ b/absl/container/fixed_array_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/fixed_array_exception_safety_test.cc b/absl/container/fixed_array_exception_safety_test.cc index da63dbfe..826eca61 100644 --- a/absl/container/fixed_array_exception_safety_test.cc +++ b/absl/container/fixed_array_exception_safety_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/fixed_array_test.cc b/absl/container/fixed_array_test.cc index 23cf7bb6..a4f2498b 100644 --- a/absl/container/fixed_array_test.cc +++ b/absl/container/fixed_array_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h index f6d28472..dfc497b5 100644 --- a/absl/container/flat_hash_map.h +++ b/absl/container/flat_hash_map.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc index 7340a747..562305e4 100644 --- a/absl/container/flat_hash_map_test.cc +++ b/absl/container/flat_hash_map_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/flat_hash_set.h b/absl/container/flat_hash_set.h index 84984cc4..f27f174c 100644 --- a/absl/container/flat_hash_set.h +++ b/absl/container/flat_hash_set.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/flat_hash_set_test.cc b/absl/container/flat_hash_set_test.cc index ae159a24..b55be59b 100644 --- a/absl/container/flat_hash_set_test.cc +++ b/absl/container/flat_hash_set_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index e8daf6af..80929e36 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/inlined_vector_benchmark.cc b/absl/container/inlined_vector_benchmark.cc index ddd7b33c..fc928afe 100644 --- a/absl/container/inlined_vector_benchmark.cc +++ b/absl/container/inlined_vector_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc index 5b1527e9..6037001a 100644 --- a/absl/container/inlined_vector_test.cc +++ b/absl/container/inlined_vector_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h index aca1a95d..b06e7113 100644 --- a/absl/container/internal/common.h +++ b/absl/container/internal/common.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/compressed_tuple.h b/absl/container/internal/compressed_tuple.h index b883ae26..b9bd91af 100644 --- a/absl/container/internal/compressed_tuple.h +++ b/absl/container/internal/compressed_tuple.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -27,7 +27,7 @@ // const T2& t2 = value.get<2>(); // ... // -// http://en.cppreference.com/w/cpp/language/ebo +// https://en.cppreference.com/w/cpp/language/ebo #ifndef ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ #define ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ @@ -141,7 +141,7 @@ struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC // const T2& t2 = value.get<2>(); // ... // -// http://en.cppreference.com/w/cpp/language/ebo +// https://en.cppreference.com/w/cpp/language/ebo template class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple : private internal_compressed_tuple::CompressedTupleImpl< diff --git a/absl/container/internal/compressed_tuple_test.cc b/absl/container/internal/compressed_tuple_test.cc index 04ead100..28e7741c 100644 --- a/absl/container/internal/compressed_tuple_test.cc +++ b/absl/container/internal/compressed_tuple_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h index 3a3f9703..e5bb9773 100644 --- a/absl/container/internal/container_memory.h +++ b/absl/container/internal/container_memory.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/container_memory_test.cc b/absl/container/internal/container_memory_test.cc index f1c40582..d6b0495f 100644 --- a/absl/container/internal/container_memory_test.cc +++ b/absl/container/internal/container_memory_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/counting_allocator.h b/absl/container/internal/counting_allocator.h index f4e652d9..4e717bef 100644 --- a/absl/container/internal/counting_allocator.h +++ b/absl/container/internal/counting_allocator.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hash_function_defaults.h b/absl/container/internal/hash_function_defaults.h index 6d112c79..cb8f03c8 100644 --- a/absl/container/internal/hash_function_defaults.h +++ b/absl/container/internal/hash_function_defaults.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hash_function_defaults_test.cc b/absl/container/internal/hash_function_defaults_test.cc index cc13576d..82708dbe 100644 --- a/absl/container/internal/hash_function_defaults_test.cc +++ b/absl/container/internal/hash_function_defaults_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hash_generator_testing.cc b/absl/container/internal/hash_generator_testing.cc index e0fefbff..37a23d60 100644 --- a/absl/container/internal/hash_generator_testing.cc +++ b/absl/container/internal/hash_generator_testing.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hash_generator_testing.h b/absl/container/internal/hash_generator_testing.h index 6521efe8..27fb84f5 100644 --- a/absl/container/internal/hash_generator_testing.h +++ b/absl/container/internal/hash_generator_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hash_policy_testing.h b/absl/container/internal/hash_policy_testing.h index 7fb819a7..c57407a0 100644 --- a/absl/container/internal/hash_policy_testing.h +++ b/absl/container/internal/hash_policy_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hash_policy_testing_test.cc b/absl/container/internal/hash_policy_testing_test.cc index c215c423..0c95eb5e 100644 --- a/absl/container/internal/hash_policy_testing_test.cc +++ b/absl/container/internal/hash_policy_testing_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hash_policy_traits.h b/absl/container/internal/hash_policy_traits.h index ace50a6c..fd007de7 100644 --- a/absl/container/internal/hash_policy_traits.h +++ b/absl/container/internal/hash_policy_traits.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hash_policy_traits_test.cc b/absl/container/internal/hash_policy_traits_test.cc index 423f1548..e643d189 100644 --- a/absl/container/internal/hash_policy_traits_test.cc +++ b/absl/container/internal/hash_policy_traits_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hashtable_debug.h b/absl/container/internal/hashtable_debug.h index 38050c69..71930004 100644 --- a/absl/container/internal/hashtable_debug.h +++ b/absl/container/internal/hashtable_debug.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hashtable_debug_hooks.h b/absl/container/internal/hashtable_debug_hooks.h index 8f219726..371ce81f 100644 --- a/absl/container/internal/hashtable_debug_hooks.h +++ b/absl/container/internal/hashtable_debug_hooks.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index dc669248..6667d3ad 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index 547954f7..aff8d15f 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc index 38a3f260..4ca6ffda 100644 --- a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc +++ b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index a6e4ac81..d2435ed8 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/have_sse.h b/absl/container/internal/have_sse.h index 29347889..43414418 100644 --- a/absl/container/internal/have_sse.h +++ b/absl/container/internal/have_sse.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/layout.h b/absl/container/internal/layout.h index 98a72be1..bbdde507 100644 --- a/absl/container/internal/layout.h +++ b/absl/container/internal/layout.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/layout_test.cc b/absl/container/internal/layout_test.cc index 301e9f78..33b72bd3 100644 --- a/absl/container/internal/layout_test.cc +++ b/absl/container/internal/layout_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/node_hash_policy.h b/absl/container/internal/node_hash_policy.h index 065e7009..19b4fc09 100644 --- a/absl/container/internal/node_hash_policy.h +++ b/absl/container/internal/node_hash_policy.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/node_hash_policy_test.cc b/absl/container/internal/node_hash_policy_test.cc index 43d287e3..f1d3ec30 100644 --- a/absl/container/internal/node_hash_policy_test.cc +++ b/absl/container/internal/node_hash_policy_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h index e0f5c07c..0014cf80 100644 --- a/absl/container/internal/raw_hash_map.h +++ b/absl/container/internal/raw_hash_map.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc index 180d3fe5..ac2d10a7 100644 --- a/absl/container/internal/raw_hash_set.cc +++ b/absl/container/internal/raw_hash_set.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 8814eb87..c4f198bb 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -515,7 +515,7 @@ inline size_t GrowthToLowerboundCapacity(size_t growth) { // if they are equal, false if they are not. If two keys compare equal, then // their hash values as defined by Hash MUST be equal. // -// Allocator: an Allocator [http://devdocs.io/cpp/concept/allocator] with which +// Allocator: an Allocator [https://devdocs.io/cpp/concept/allocator] with which // the storage of the hashtable will be allocated and the elements will be // constructed and destroyed. template diff --git a/absl/container/internal/raw_hash_set_allocator_test.cc b/absl/container/internal/raw_hash_set_allocator_test.cc index 891fa450..a5eff0b3 100644 --- a/absl/container/internal/raw_hash_set_allocator_test.cc +++ b/absl/container/internal/raw_hash_set_allocator_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index f599fd3d..b684571f 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/test_instance_tracker.cc b/absl/container/internal/test_instance_tracker.cc index b18e0bb7..5a66cb4d 100644 --- a/absl/container/internal/test_instance_tracker.cc +++ b/absl/container/internal/test_instance_tracker.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/test_instance_tracker.h b/absl/container/internal/test_instance_tracker.h index ec45f574..032d16d3 100644 --- a/absl/container/internal/test_instance_tracker.h +++ b/absl/container/internal/test_instance_tracker.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/test_instance_tracker_test.cc b/absl/container/internal/test_instance_tracker_test.cc index 0ae57636..091f428d 100644 --- a/absl/container/internal/test_instance_tracker_test.cc +++ b/absl/container/internal/test_instance_tracker_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/tracked.h b/absl/container/internal/tracked.h index 7d14af03..75173ab0 100644 --- a/absl/container/internal/tracked.h +++ b/absl/container/internal/tracked.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/unordered_map_constructor_test.h b/absl/container/internal/unordered_map_constructor_test.h index 837d2317..68817e4e 100644 --- a/absl/container/internal/unordered_map_constructor_test.h +++ b/absl/container/internal/unordered_map_constructor_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/unordered_map_lookup_test.h b/absl/container/internal/unordered_map_lookup_test.h index 488e340d..ebd3612b 100644 --- a/absl/container/internal/unordered_map_lookup_test.h +++ b/absl/container/internal/unordered_map_lookup_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/unordered_map_modifiers_test.h b/absl/container/internal/unordered_map_modifiers_test.h index 2e1cd633..52a1092e 100644 --- a/absl/container/internal/unordered_map_modifiers_test.h +++ b/absl/container/internal/unordered_map_modifiers_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/unordered_map_test.cc b/absl/container/internal/unordered_map_test.cc index 32ab48d0..72567eac 100644 --- a/absl/container/internal/unordered_map_test.cc +++ b/absl/container/internal/unordered_map_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/unordered_set_constructor_test.h b/absl/container/internal/unordered_set_constructor_test.h index 533a6217..f4844683 100644 --- a/absl/container/internal/unordered_set_constructor_test.h +++ b/absl/container/internal/unordered_set_constructor_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/unordered_set_lookup_test.h b/absl/container/internal/unordered_set_lookup_test.h index 69f43142..05b32b5d 100644 --- a/absl/container/internal/unordered_set_lookup_test.h +++ b/absl/container/internal/unordered_set_lookup_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/unordered_set_modifiers_test.h b/absl/container/internal/unordered_set_modifiers_test.h index 853c4e31..79a8d422 100644 --- a/absl/container/internal/unordered_set_modifiers_test.h +++ b/absl/container/internal/unordered_set_modifiers_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/internal/unordered_set_test.cc b/absl/container/internal/unordered_set_test.cc index 1a340af8..6478fac1 100644 --- a/absl/container/internal/unordered_set_test.cc +++ b/absl/container/internal/unordered_set_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h index bd53c590..a841f5ab 100644 --- a/absl/container/node_hash_map.h +++ b/absl/container/node_hash_map.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/node_hash_map_test.cc b/absl/container/node_hash_map_test.cc index 87fd4185..0f2714a7 100644 --- a/absl/container/node_hash_map_test.cc +++ b/absl/container/node_hash_map_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h index 843b11aa..0cd1fe57 100644 --- a/absl/container/node_hash_set.h +++ b/absl/container/node_hash_set.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/container/node_hash_set_test.cc b/absl/container/node_hash_set_test.cc index 5eaac2a5..0ea76e7c 100644 --- a/absl/container/node_hash_set_test.cc +++ b/absl/container/node_hash_set_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index 84b994da..c9184f92 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index 34511521..dccd4a56 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc index c2e56f9d..c6a4d962 100644 --- a/absl/debugging/failure_signal_handler.cc +++ b/absl/debugging/failure_signal_handler.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/failure_signal_handler.h b/absl/debugging/failure_signal_handler.h index c57954e5..1beb78b9 100644 --- a/absl/debugging/failure_signal_handler.h +++ b/absl/debugging/failure_signal_handler.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/failure_signal_handler_test.cc b/absl/debugging/failure_signal_handler_test.cc index 15e888be..bb2cc48e 100644 --- a/absl/debugging/failure_signal_handler_test.cc +++ b/absl/debugging/failure_signal_handler_test.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/address_is_readable.cc b/absl/debugging/internal/address_is_readable.cc index 7455aa0b..99c4c64b 100644 --- a/absl/debugging/internal/address_is_readable.cc +++ b/absl/debugging/internal/address_is_readable.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/address_is_readable.h b/absl/debugging/internal/address_is_readable.h index 9d480300..64c3f1ea 100644 --- a/absl/debugging/internal/address_is_readable.h +++ b/absl/debugging/internal/address_is_readable.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 3ee3df51..0d959a98 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -749,8 +749,8 @@ static bool ParseSourceName(State *state) { // ::= L [] // // References: -// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 -// http://gcc.gnu.org/viewcvs?view=rev&revision=124467 +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 +// https://gcc.gnu.org/viewcvs?view=rev&revision=124467 static bool ParseLocalSourceName(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; diff --git a/absl/debugging/internal/demangle.h b/absl/debugging/internal/demangle.h index 2e75564e..81bb0dfd 100644 --- a/absl/debugging/internal/demangle.h +++ b/absl/debugging/internal/demangle.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index b9d9008f..d410a232 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/elf_mem_image.cc b/absl/debugging/internal/elf_mem_image.cc index 3f747e7f..e7408bca 100644 --- a/absl/debugging/internal/elf_mem_image.cc +++ b/absl/debugging/internal/elf_mem_image.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/elf_mem_image.h b/absl/debugging/internal/elf_mem_image.h index 3b577268..99b37580 100644 --- a/absl/debugging/internal/elf_mem_image.h +++ b/absl/debugging/internal/elf_mem_image.h @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/absl/debugging/internal/examine_stack.cc b/absl/debugging/internal/examine_stack.cc index faf88836..1ebc788f 100644 --- a/absl/debugging/internal/examine_stack.cc +++ b/absl/debugging/internal/examine_stack.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/examine_stack.h b/absl/debugging/internal/examine_stack.h index a16c03b2..56c9763e 100644 --- a/absl/debugging/internal/examine_stack.h +++ b/absl/debugging/internal/examine_stack.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/stack_consumption.cc b/absl/debugging/internal/stack_consumption.cc index 2b3b972e..4b05f495 100644 --- a/absl/debugging/internal/stack_consumption.cc +++ b/absl/debugging/internal/stack_consumption.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/stack_consumption.h b/absl/debugging/internal/stack_consumption.h index 4c5fa0f0..b860a3c1 100644 --- a/absl/debugging/internal/stack_consumption.h +++ b/absl/debugging/internal/stack_consumption.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/stack_consumption_test.cc b/absl/debugging/internal/stack_consumption_test.cc index 5ce3846e..68bfa126 100644 --- a/absl/debugging/internal/stack_consumption_test.cc +++ b/absl/debugging/internal/stack_consumption_test.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/stacktrace_config.h b/absl/debugging/internal/stacktrace_config.h index 578e4968..d4e8480a 100644 --- a/absl/debugging/internal/stacktrace_config.h +++ b/absl/debugging/internal/stacktrace_config.h @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/absl/debugging/internal/stacktrace_powerpc-inl.inc b/absl/debugging/internal/stacktrace_powerpc-inl.inc index 860ac2b3..9e0f2aad 100644 --- a/absl/debugging/internal/stacktrace_powerpc-inl.inc +++ b/absl/debugging/internal/stacktrace_powerpc-inl.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -14,8 +14,8 @@ // // Produce stack trace. I'm guessing (hoping!) the code is much like // for x86. For apple machines, at least, it seems to be; see -// http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html -// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK +// https://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html +// https://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK // Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882 #ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_ diff --git a/absl/debugging/internal/stacktrace_win32-inl.inc b/absl/debugging/internal/stacktrace_win32-inl.inc index a8f8a56a..b46491f8 100644 --- a/absl/debugging/internal/stacktrace_win32-inl.inc +++ b/absl/debugging/internal/stacktrace_win32-inl.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -32,7 +32,7 @@ // server. // // This code is inspired by a patch from David Vitek: -// http://code.google.com/p/google-perftools/issues/detail?id=83 +// https://code.google.com/p/google-perftools/issues/detail?id=83 #ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_WIN32_INL_H_ #define ABSL_DEBUGGING_INTERNAL_STACKTRACE_WIN32_INL_H_ diff --git a/absl/debugging/internal/stacktrace_x86-inl.inc b/absl/debugging/internal/stacktrace_x86-inl.inc index ac85b920..248966b0 100644 --- a/absl/debugging/internal/stacktrace_x86-inl.inc +++ b/absl/debugging/internal/stacktrace_x86-inl.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/symbolize.h b/absl/debugging/internal/symbolize.h index d719eda9..3e537893 100644 --- a/absl/debugging/internal/symbolize.h +++ b/absl/debugging/internal/symbolize.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/vdso_support.cc b/absl/debugging/internal/vdso_support.cc index 44ec7c02..d13ef25d 100644 --- a/absl/debugging/internal/vdso_support.cc +++ b/absl/debugging/internal/vdso_support.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/internal/vdso_support.h b/absl/debugging/internal/vdso_support.h index 8002c740..9895b48d 100644 --- a/absl/debugging/internal/vdso_support.h +++ b/absl/debugging/internal/vdso_support.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/leak_check.cc b/absl/debugging/leak_check.cc index e01e5f8c..a1cae969 100644 --- a/absl/debugging/leak_check.cc +++ b/absl/debugging/leak_check.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/leak_check.h b/absl/debugging/leak_check.h index c930684e..4d489c58 100644 --- a/absl/debugging/leak_check.h +++ b/absl/debugging/leak_check.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/leak_check_disable.cc b/absl/debugging/leak_check_disable.cc index df22c1ca..924d6e3d 100644 --- a/absl/debugging/leak_check_disable.cc +++ b/absl/debugging/leak_check_disable.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/leak_check_fail_test.cc b/absl/debugging/leak_check_fail_test.cc index bf541fe8..2887ceab 100644 --- a/absl/debugging/leak_check_fail_test.cc +++ b/absl/debugging/leak_check_fail_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/leak_check_test.cc b/absl/debugging/leak_check_test.cc index febd1ee4..93a7edd2 100644 --- a/absl/debugging/leak_check_test.cc +++ b/absl/debugging/leak_check_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/stacktrace.cc b/absl/debugging/stacktrace.cc index 7bbd65ac..9935adfa 100644 --- a/absl/debugging/stacktrace.cc +++ b/absl/debugging/stacktrace.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/stacktrace.h b/absl/debugging/stacktrace.h index 8b831e26..3fc1c03f 100644 --- a/absl/debugging/stacktrace.h +++ b/absl/debugging/stacktrace.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/symbolize.cc b/absl/debugging/symbolize.cc index a35e24cc..24e3a7f0 100644 --- a/absl/debugging/symbolize.cc +++ b/absl/debugging/symbolize.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/symbolize.h b/absl/debugging/symbolize.h index 24e6e647..a73dbd9e 100644 --- a/absl/debugging/symbolize.h +++ b/absl/debugging/symbolize.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc index 5b16bb8b..05fc2979 100644 --- a/absl/debugging/symbolize_elf.inc +++ b/absl/debugging/symbolize_elf.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc index dcb52695..fc3ed93e 100644 --- a/absl/debugging/symbolize_test.cc +++ b/absl/debugging/symbolize_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/symbolize_unimplemented.inc b/absl/debugging/symbolize_unimplemented.inc index 98b3a9ae..7c580fe4 100644 --- a/absl/debugging/symbolize_unimplemented.inc +++ b/absl/debugging/symbolize_unimplemented.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/debugging/symbolize_win32.inc b/absl/debugging/symbolize_win32.inc index e3fff74d..17ea618a 100644 --- a/absl/debugging/symbolize_win32.inc +++ b/absl/debugging/symbolize_win32.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/hash/BUILD.bazel b/absl/hash/BUILD.bazel index 5f24b999..69860d98 100644 --- a/absl/hash/BUILD.bazel +++ b/absl/hash/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/hash/CMakeLists.txt b/absl/hash/CMakeLists.txt index 8f97d7cc..4cafc133 100644 --- a/absl/hash/CMakeLists.txt +++ b/absl/hash/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/hash/hash.h b/absl/hash/hash.h index 3b1d6eab..94cb6747 100644 --- a/absl/hash/hash.h +++ b/absl/hash/hash.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index 97c3449a..d9ebd30f 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/hash/hash_testing.h b/absl/hash/hash_testing.h index 06d09499..c45bc154 100644 --- a/absl/hash/hash_testing.h +++ b/absl/hash/hash_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/hash/internal/city.cc b/absl/hash/internal/city.cc index 122906fa..dc7650a7 100644 --- a/absl/hash/internal/city.cc +++ b/absl/hash/internal/city.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/hash/internal/city.h b/absl/hash/internal/city.h index 16df5563..1b3b4ef9 100644 --- a/absl/hash/internal/city.h +++ b/absl/hash/internal/city.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// http://code.google.com/p/cityhash/ +// https://code.google.com/p/cityhash/ // // This file provides a few functions for hashing strings. All of them are // high-quality functions in the sense that they pass standard tests such diff --git a/absl/hash/internal/city_test.cc b/absl/hash/internal/city_test.cc index 0427cd1a..71b4ecce 100644 --- a/absl/hash/internal/city_test.cc +++ b/absl/hash/internal/city_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/hash/internal/hash.cc b/absl/hash/internal/hash.cc index 4bf64096..4ab7a9f8 100644 --- a/absl/hash/internal/hash.cc +++ b/absl/hash/internal/hash.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 4db816c7..2a45bc84 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/hash/internal/print_hash_of.cc b/absl/hash/internal/print_hash_of.cc index b6df31cc..c392125a 100644 --- a/absl/hash/internal/print_hash_of.cc +++ b/absl/hash/internal/print_hash_of.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/hash/internal/spy_hash_state.h b/absl/hash/internal/spy_hash_state.h index 102e05de..c4cc8d07 100644 --- a/absl/hash/internal/spy_hash_state.h +++ b/absl/hash/internal/spy_hash_state.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/memory/BUILD.bazel b/absl/memory/BUILD.bazel index c0da9ce1..7c6366fe 100644 --- a/absl/memory/BUILD.bazel +++ b/absl/memory/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/memory/CMakeLists.txt b/absl/memory/CMakeLists.txt index 4b494dc0..0a812203 100644 --- a/absl/memory/CMakeLists.txt +++ b/absl/memory/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/memory/memory.h b/absl/memory/memory.h index 75506a74..a0d0714f 100644 --- a/absl/memory/memory.h +++ b/absl/memory/memory.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -120,7 +120,7 @@ using std::make_unique; // // For more background on why `std::unique_ptr(new T(a,b))` is problematic, // see Herb Sutter's explanation on -// (Exception-Safe Function Calls)[http://herbsutter.com/gotw/_102/]. +// (Exception-Safe Function Calls)[https://herbsutter.com/gotw/_102/]. // (In general, reviewers should treat `new T(a,b)` with scrutiny.) // // Example usage: diff --git a/absl/memory/memory_exception_safety_test.cc b/absl/memory/memory_exception_safety_test.cc index 00d2b192..a1c39707 100644 --- a/absl/memory/memory_exception_safety_test.cc +++ b/absl/memory/memory_exception_safety_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/memory/memory_test.cc b/absl/memory/memory_test.cc index 21fe32f9..8905433c 100644 --- a/absl/memory/memory_test.cc +++ b/absl/memory/memory_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/meta/CMakeLists.txt b/absl/meta/CMakeLists.txt index 4358db57..74d4a543 100644 --- a/absl/meta/CMakeLists.txt +++ b/absl/meta/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index 88853974..8a788dea 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -22,7 +22,7 @@ // support type inference, classification, and transformation, as well as // make it easier to write templates based on generic type behavior. // -// See http://en.cppreference.com/w/cpp/header/type_traits +// See https://en.cppreference.com/w/cpp/header/type_traits // // WARNING: use of many of the constructs in this header will count as "complex // template metaprogramming", so before proceeding, please carefully consider @@ -246,7 +246,7 @@ struct is_trivially_destructible // For the purposes of this check, the call to std::declval is considered // trivial." // -// Notes from http://en.cppreference.com/w/cpp/types/is_constructible: +// Notes from https://en.cppreference.com/w/cpp/types/is_constructible: // In many implementations, is_nothrow_constructible also checks if the // destructor throws because it is effectively noexcept(T(arg)). Same // applies to is_trivially_constructible, which, in these implementations, also diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc index f51f5ded..29a6db69 100644 --- a/absl/meta/type_traits_test.cc +++ b/absl/meta/type_traits_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/numeric/BUILD.bazel b/absl/numeric/BUILD.bazel index c906b8d7..7cd7ee19 100644 --- a/absl/numeric/BUILD.bazel +++ b/absl/numeric/BUILD.bazel @@ -4,7 +4,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/numeric/CMakeLists.txt b/absl/numeric/CMakeLists.txt index 42468a6a..d26141c7 100644 --- a/absl/numeric/CMakeLists.txt +++ b/absl/numeric/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc index 3c37f252..33f528ce 100644 --- a/absl/numeric/int128.cc +++ b/absl/numeric/int128.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -65,7 +65,7 @@ static inline int Fls128(uint128 n) { // Long division/modulo for uint128 implemented using the shift-subtract // division algorithm adapted from: -// http://stackoverflow.com/questions/5386377/division-without-using +// https://stackoverflow.com/questions/5386377/division-without-using void DivModImpl(uint128 dividend, uint128 divisor, uint128* quotient_ret, uint128* remainder_ret) { assert(divisor != 0); diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 3e7d2d9f..c0ec03d4 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/numeric/int128_benchmark.cc b/absl/numeric/int128_benchmark.cc index 1cb7d0ed..a5502d92 100644 --- a/absl/numeric/int128_benchmark.cc +++ b/absl/numeric/int128_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/numeric/int128_have_intrinsic.inc b/absl/numeric/int128_have_intrinsic.inc index 0c8164a5..c7ea6834 100644 --- a/absl/numeric/int128_have_intrinsic.inc +++ b/absl/numeric/int128_have_intrinsic.inc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/numeric/int128_no_intrinsic.inc b/absl/numeric/int128_no_intrinsic.inc index 08d68ac3..046cb9b3 100644 --- a/absl/numeric/int128_no_intrinsic.inc +++ b/absl/numeric/int128_no_intrinsic.inc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/numeric/int128_stream_test.cc b/absl/numeric/int128_stream_test.cc index 09efaad4..3cfa9dc1 100644 --- a/absl/numeric/int128_stream_test.cc +++ b/absl/numeric/int128_stream_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/numeric/int128_test.cc b/absl/numeric/int128_test.cc index 4a6eb455..216ec50c 100644 --- a/absl/numeric/int128_test.cc +++ b/absl/numeric/int128_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index 7635a619..8afe8177 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index aed54dc4..d3393a39 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/strings/ascii.cc b/absl/strings/ascii.cc index c9481e88..3f7c581f 100644 --- a/absl/strings/ascii.cc +++ b/absl/strings/ascii.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/ascii.h b/absl/strings/ascii.h index 48a9da22..f9e4fd1d 100644 --- a/absl/strings/ascii.h +++ b/absl/strings/ascii.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/ascii_benchmark.cc b/absl/strings/ascii_benchmark.cc index 8dea4b8c..aca458c8 100644 --- a/absl/strings/ascii_benchmark.cc +++ b/absl/strings/ascii_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/ascii_test.cc b/absl/strings/ascii_test.cc index 9903b049..5ecd23f8 100644 --- a/absl/strings/ascii_test.cc +++ b/absl/strings/ascii_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/charconv.cc b/absl/strings/charconv.cc index d0aa1913..bc07e7ab 100644 --- a/absl/strings/charconv.cc +++ b/absl/strings/charconv.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/charconv.h b/absl/strings/charconv.h index 07353829..59f74bf0 100644 --- a/absl/strings/charconv.h +++ b/absl/strings/charconv.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/charconv_benchmark.cc b/absl/strings/charconv_benchmark.cc index fd83f44e..644b2abd 100644 --- a/absl/strings/charconv_benchmark.cc +++ b/absl/strings/charconv_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/charconv_test.cc b/absl/strings/charconv_test.cc index d6a0a759..b58fad26 100644 --- a/absl/strings/charconv_test.cc +++ b/absl/strings/charconv_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc index 0950ab9e..bc8307e1 100644 --- a/absl/strings/escaping.cc +++ b/absl/strings/escaping.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -788,7 +788,7 @@ size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { // Base64 encodes three bytes of input at a time. If the input is not // divisible by three, we pad as appropriate. // - // (from http://tools.ietf.org/html/rfc3548) + // (from https://tools.ietf.org/html/rfc3548) // Special processing is performed if fewer than 24 bits are available // at the end of the data being encoded. A full encoding quantum is // always completed at the end of a quantity. When fewer than 24 input @@ -802,12 +802,12 @@ size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { size_t len = (input_len / 3) * 4; if (input_len % 3 == 0) { - // (from http://tools.ietf.org/html/rfc3548) + // (from https://tools.ietf.org/html/rfc3548) // (1) the final quantum of encoding input is an integral multiple of 24 // bits; here, the final unit of encoded output will be an integral // multiple of 4 characters with no "=" padding, } else if (input_len % 3 == 1) { - // (from http://tools.ietf.org/html/rfc3548) + // (from https://tools.ietf.org/html/rfc3548) // (2) the final quantum of encoding input is exactly 8 bits; here, the // final unit of encoded output will be two characters followed by two // "=" padding characters, or @@ -816,7 +816,7 @@ size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { len += 2; } } else { // (input_len % 3 == 2) - // (from http://tools.ietf.org/html/rfc3548) + // (from https://tools.ietf.org/html/rfc3548) // (3) the final quantum of encoding input is exactly 16 bits; here, the // final unit of encoded output will be three characters followed by one // "=" padding character. diff --git a/absl/strings/escaping.h b/absl/strings/escaping.h index 29659730..03ab0ae7 100644 --- a/absl/strings/escaping.h +++ b/absl/strings/escaping.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -38,7 +38,7 @@ namespace absl { // CUnescape() // // Unescapes a `source` string and copies it into `dest`, rewriting C-style -// escape sequences (http://en.cppreference.com/w/cpp/language/escape) into +// escape sequences (https://en.cppreference.com/w/cpp/language/escape) into // their proper code point equivalents, returning `true` if successful. // // The following unescape sequences can be handled: @@ -80,7 +80,7 @@ inline bool CUnescape(absl::string_view source, std::string* dest) { // CEscape() // // Escapes a 'src' string using C-style escapes sequences -// (http://en.cppreference.com/w/cpp/language/escape), escaping other +// (https://en.cppreference.com/w/cpp/language/escape), escaping other // non-printable/non-whitespace bytes as octal sequences (e.g. "\377"). // // Example: diff --git a/absl/strings/escaping_benchmark.cc b/absl/strings/escaping_benchmark.cc index 0f791f4e..10d5b033 100644 --- a/absl/strings/escaping_benchmark.cc +++ b/absl/strings/escaping_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/escaping_test.cc b/absl/strings/escaping_test.cc index 77846dd2..d433b4c5 100644 --- a/absl/strings/escaping_test.cc +++ b/absl/strings/escaping_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/char_map.h b/absl/strings/internal/char_map.h index 8d92963a..b9108b8c 100644 --- a/absl/strings/internal/char_map.h +++ b/absl/strings/internal/char_map.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/char_map_benchmark.cc b/absl/strings/internal/char_map_benchmark.cc index c45f3157..5cef967b 100644 --- a/absl/strings/internal/char_map_benchmark.cc +++ b/absl/strings/internal/char_map_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/char_map_test.cc b/absl/strings/internal/char_map_test.cc index c3601e10..d3306241 100644 --- a/absl/strings/internal/char_map_test.cc +++ b/absl/strings/internal/char_map_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/charconv_bigint.cc b/absl/strings/internal/charconv_bigint.cc index 3e7296e7..95d471d9 100644 --- a/absl/strings/internal/charconv_bigint.cc +++ b/absl/strings/internal/charconv_bigint.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/charconv_bigint.h b/absl/strings/internal/charconv_bigint.h index 9d1a1bff..7da9a7e7 100644 --- a/absl/strings/internal/charconv_bigint.h +++ b/absl/strings/internal/charconv_bigint.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/charconv_bigint_test.cc b/absl/strings/internal/charconv_bigint_test.cc index 9b635788..745714ac 100644 --- a/absl/strings/internal/charconv_bigint_test.cc +++ b/absl/strings/internal/charconv_bigint_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/charconv_parse.cc b/absl/strings/internal/charconv_parse.cc index 7e4dabc2..f3c72324 100644 --- a/absl/strings/internal/charconv_parse.cc +++ b/absl/strings/internal/charconv_parse.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/charconv_parse.h b/absl/strings/internal/charconv_parse.h index 7a5c0874..44d06b2e 100644 --- a/absl/strings/internal/charconv_parse.h +++ b/absl/strings/internal/charconv_parse.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/charconv_parse_test.cc b/absl/strings/internal/charconv_parse_test.cc index f48b9aee..9511c987 100644 --- a/absl/strings/internal/charconv_parse_test.cc +++ b/absl/strings/internal/charconv_parse_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/escaping_test_common.h b/absl/strings/internal/escaping_test_common.h index cc41f431..bd803031 100644 --- a/absl/strings/internal/escaping_test_common.h +++ b/absl/strings/internal/escaping_test_common.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/memutil.cc b/absl/strings/internal/memutil.cc index a0de70df..77aa63c2 100644 --- a/absl/strings/internal/memutil.cc +++ b/absl/strings/internal/memutil.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/memutil.h b/absl/strings/internal/memutil.h index 7de383b1..7c071a82 100644 --- a/absl/strings/internal/memutil.h +++ b/absl/strings/internal/memutil.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/memutil_benchmark.cc b/absl/strings/internal/memutil_benchmark.cc index 77915adb..dc95c3e5 100644 --- a/absl/strings/internal/memutil_benchmark.cc +++ b/absl/strings/internal/memutil_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/memutil_test.cc b/absl/strings/internal/memutil_test.cc index 09424de9..d8681ddf 100644 --- a/absl/strings/internal/memutil_test.cc +++ b/absl/strings/internal/memutil_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/numbers_test_common.h b/absl/strings/internal/numbers_test_common.h index f6241ff3..28247205 100644 --- a/absl/strings/internal/numbers_test_common.h +++ b/absl/strings/internal/numbers_test_common.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/ostringstream.cc b/absl/strings/internal/ostringstream.cc index 6ee2b109..d0f0f84b 100644 --- a/absl/strings/internal/ostringstream.cc +++ b/absl/strings/internal/ostringstream.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/ostringstream.h b/absl/strings/internal/ostringstream.h index 316379ca..20792015 100644 --- a/absl/strings/internal/ostringstream.h +++ b/absl/strings/internal/ostringstream.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/ostringstream_benchmark.cc b/absl/strings/internal/ostringstream_benchmark.cc index c93f9690..5979f182 100644 --- a/absl/strings/internal/ostringstream_benchmark.cc +++ b/absl/strings/internal/ostringstream_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/ostringstream_test.cc b/absl/strings/internal/ostringstream_test.cc index 069a0e1f..2879e50e 100644 --- a/absl/strings/internal/ostringstream_test.cc +++ b/absl/strings/internal/ostringstream_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/pow10_helper.cc b/absl/strings/internal/pow10_helper.cc index 66be163f..03ed8d07 100644 --- a/absl/strings/internal/pow10_helper.cc +++ b/absl/strings/internal/pow10_helper.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/pow10_helper.h b/absl/strings/internal/pow10_helper.h index fe7e735a..9d1aa710 100644 --- a/absl/strings/internal/pow10_helper.h +++ b/absl/strings/internal/pow10_helper.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/pow10_helper_test.cc b/absl/strings/internal/pow10_helper_test.cc index 9a13d524..a4a68b5d 100644 --- a/absl/strings/internal/pow10_helper_test.cc +++ b/absl/strings/internal/pow10_helper_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/resize_uninitialized.h b/absl/strings/internal/resize_uninitialized.h index 25d602b1..469962b2 100644 --- a/absl/strings/internal/resize_uninitialized.h +++ b/absl/strings/internal/resize_uninitialized.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/resize_uninitialized_test.cc b/absl/strings/internal/resize_uninitialized_test.cc index 43aece8d..c5be0b12 100644 --- a/absl/strings/internal/resize_uninitialized_test.cc +++ b/absl/strings/internal/resize_uninitialized_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/stl_type_traits.h b/absl/strings/internal/stl_type_traits.h index 04c4a532..202ab374 100644 --- a/absl/strings/internal/stl_type_traits.h +++ b/absl/strings/internal/stl_type_traits.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/str_format/arg_test.cc b/absl/strings/internal/str_format/arg_test.cc index 83d59048..3421fac1 100644 --- a/absl/strings/internal/str_format/arg_test.cc +++ b/absl/strings/internal/str_format/arg_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // #include "absl/strings/internal/str_format/arg.h" diff --git a/absl/strings/internal/str_format/extension.cc b/absl/strings/internal/str_format/extension.cc index c2174703..d7f58159 100644 --- a/absl/strings/internal/str_format/extension.cc +++ b/absl/strings/internal/str_format/extension.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index 55be9284..30235e08 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/str_format/extension_test.cc b/absl/strings/internal/str_format/extension_test.cc index 224fc923..334a1484 100644 --- a/absl/strings/internal/str_format/extension_test.cc +++ b/absl/strings/internal/str_format/extension_test.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/str_format/output.cc b/absl/strings/internal/str_format/output.cc index d7fef69b..38987b63 100644 --- a/absl/strings/internal/str_format/output.cc +++ b/absl/strings/internal/str_format/output.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/str_format/output.h b/absl/strings/internal/str_format/output.h index 12ecd99e..42da6417 100644 --- a/absl/strings/internal/str_format/output.h +++ b/absl/strings/internal/str_format/output.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/str_format/output_test.cc b/absl/strings/internal/str_format/output_test.cc index 305cc6e6..ca93d1e3 100644 --- a/absl/strings/internal/str_format/output_test.cc +++ b/absl/strings/internal/str_format/output_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/str_join_internal.h b/absl/strings/internal/str_join_internal.h index 6281da6e..7c35f4de 100644 --- a/absl/strings/internal/str_join_internal.h +++ b/absl/strings/internal/str_join_internal.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/str_split_internal.h b/absl/strings/internal/str_split_internal.h index 34390a91..52f62226 100644 --- a/absl/strings/internal/str_split_internal.h +++ b/absl/strings/internal/str_split_internal.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/utf8.cc b/absl/strings/internal/utf8.cc index 2415c2cc..82d36c24 100644 --- a/absl/strings/internal/utf8.cc +++ b/absl/strings/internal/utf8.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/utf8.h b/absl/strings/internal/utf8.h index d2c3c0b0..445d4c35 100644 --- a/absl/strings/internal/utf8.h +++ b/absl/strings/internal/utf8.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/internal/utf8_test.cc b/absl/strings/internal/utf8_test.cc index 6ffa36cd..88dd5036 100644 --- a/absl/strings/internal/utf8_test.cc +++ b/absl/strings/internal/utf8_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/match.cc b/absl/strings/match.cc index a2e9064c..7b24241a 100644 --- a/absl/strings/match.cc +++ b/absl/strings/match.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/match.h b/absl/strings/match.h index 3a4fefd9..5251b7ff 100644 --- a/absl/strings/match.h +++ b/absl/strings/match.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/match_test.cc b/absl/strings/match_test.cc index 0dca33ae..4c313dda 100644 --- a/absl/strings/match_test.cc +++ b/absl/strings/match_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index 60c8fed1..558c3396 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h index dc02bc30..e0f96df9 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -53,7 +53,7 @@ ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, int_type* out); // // Converts the given string (optionally followed or preceded by ASCII // whitespace) into a float, which may be rounded on overflow or underflow. -// See http://en.cppreference.com/w/c/string/byte/strtof for details about the +// See https://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`. If any errors are encountered, this function // returns `false`, leaving `out` in an unspecified state. ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* out); @@ -62,7 +62,7 @@ ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* out); // // Converts the given string (optionally followed or preceded by ASCII // whitespace) into a double, which may be rounded on overflow or underflow. -// See http://en.cppreference.com/w/c/string/byte/strtof for details about the +// See https://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`. If any errors are encountered, this function // returns `false`, leaving `out` in an unspecified state. ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* out); diff --git a/absl/strings/numbers_benchmark.cc b/absl/strings/numbers_benchmark.cc index 0570b758..54dbedd3 100644 --- a/absl/strings/numbers_benchmark.cc +++ b/absl/strings/numbers_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index 7edb73eb..b7b03ff0 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_cat.cc b/absl/strings/str_cat.cc index b3a55d13..2667976d 100644 --- a/absl/strings/str_cat.cc +++ b/absl/strings/str_cat.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h index 7b5bedb0..69d6eaad 100644 --- a/absl/strings/str_cat.h +++ b/absl/strings/str_cat.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_cat_benchmark.cc b/absl/strings/str_cat_benchmark.cc index b6df9e30..14c63b3f 100644 --- a/absl/strings/str_cat_benchmark.cc +++ b/absl/strings/str_cat_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_cat_test.cc b/absl/strings/str_cat_test.cc index af459c51..beb15fa9 100644 --- a/absl/strings/str_cat_test.cc +++ b/absl/strings/str_cat_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index 4736bef1..486fe0eb 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_join.h b/absl/strings/str_join.h index 69abc9c1..7345b962 100644 --- a/absl/strings/str_join.h +++ b/absl/strings/str_join.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_join_benchmark.cc b/absl/strings/str_join_benchmark.cc index f423e123..d6f689ff 100644 --- a/absl/strings/str_join_benchmark.cc +++ b/absl/strings/str_join_benchmark.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_join_test.cc b/absl/strings/str_join_test.cc index de9c3551..921d9c2b 100644 --- a/absl/strings/str_join_test.cc +++ b/absl/strings/str_join_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_replace.cc b/absl/strings/str_replace.cc index d01b8b11..280f63d3 100644 --- a/absl/strings/str_replace.cc +++ b/absl/strings/str_replace.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_replace.h b/absl/strings/str_replace.h index 6d284042..30540d02 100644 --- a/absl/strings/str_replace.h +++ b/absl/strings/str_replace.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_replace_benchmark.cc b/absl/strings/str_replace_benchmark.cc index 07fd3a70..95b2dc10 100644 --- a/absl/strings/str_replace_benchmark.cc +++ b/absl/strings/str_replace_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_replace_test.cc b/absl/strings/str_replace_test.cc index 73c69a59..1ca23aff 100644 --- a/absl/strings/str_replace_test.cc +++ b/absl/strings/str_replace_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_split.cc b/absl/strings/str_split.cc index 0a68c52d..25931307 100644 --- a/absl/strings/str_split.cc +++ b/absl/strings/str_split.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_split.h b/absl/strings/str_split.h index dc45bc8a..8eb55089 100644 --- a/absl/strings/str_split.h +++ b/absl/strings/str_split.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_split_benchmark.cc b/absl/strings/str_split_benchmark.cc index 6280568a..28c25e8d 100644 --- a/absl/strings/str_split_benchmark.cc +++ b/absl/strings/str_split_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/str_split_test.cc b/absl/strings/str_split_test.cc index babead92..4b8e7d6b 100644 --- a/absl/strings/str_split_test.cc +++ b/absl/strings/str_split_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/string_view.cc b/absl/strings/string_view.cc index 4ceeb6bf..cb79d5df 100644 --- a/absl/strings/string_view.cc +++ b/absl/strings/string_view.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -228,7 +228,7 @@ string_view::size_type string_view::find_last_not_of(char c, // member definitions that are required by the C++ standard, resulting in // LNK1169 "multiply defined" errors at link time. __declspec(selectany) asks // MSVC to choose only one definition for the symbol it decorates. See details -// at http://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx +// at https://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx #ifdef _MSC_VER #define ABSL_STRING_VIEW_SELECTANY __declspec(selectany) #else diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 72f0f414..524dbebb 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/string_view_benchmark.cc b/absl/strings/string_view_benchmark.cc index f4420320..46909cb0 100644 --- a/absl/strings/string_view_benchmark.cc +++ b/absl/strings/string_view_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc index 2150b4e5..d439900d 100644 --- a/absl/strings/string_view_test.cc +++ b/absl/strings/string_view_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/strip.h b/absl/strings/strip.h index 8d0d7c6b..e1341e08 100644 --- a/absl/strings/strip.h +++ b/absl/strings/strip.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/strip_test.cc b/absl/strings/strip_test.cc index 67355fcb..e4e00cb6 100644 --- a/absl/strings/strip_test.cc +++ b/absl/strings/strip_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/substitute.cc b/absl/strings/substitute.cc index 3b200594..bc176950 100644 --- a/absl/strings/substitute.cc +++ b/absl/strings/substitute.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h index 2b74b382..a45ff039 100644 --- a/absl/strings/substitute.h +++ b/absl/strings/substitute.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/strings/substitute_test.cc b/absl/strings/substitute_test.cc index 144df01e..f6568906 100644 --- a/absl/strings/substitute_test.cc +++ b/absl/strings/substitute_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index 43680046..ac019041 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt index cb77b685..68473b73 100644 --- a/absl/synchronization/CMakeLists.txt +++ b/absl/synchronization/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/synchronization/barrier.cc b/absl/synchronization/barrier.cc index a1b3ad5c..c2c539ac 100644 --- a/absl/synchronization/barrier.cc +++ b/absl/synchronization/barrier.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/barrier.h b/absl/synchronization/barrier.h index f834feec..23bb2f58 100644 --- a/absl/synchronization/barrier.h +++ b/absl/synchronization/barrier.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/barrier_test.cc b/absl/synchronization/barrier_test.cc index d6cababd..bfc6cb18 100644 --- a/absl/synchronization/barrier_test.cc +++ b/absl/synchronization/barrier_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/blocking_counter.cc b/absl/synchronization/blocking_counter.cc index 7e68e960..481a06b2 100644 --- a/absl/synchronization/blocking_counter.cc +++ b/absl/synchronization/blocking_counter.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/blocking_counter.h b/absl/synchronization/blocking_counter.h index 557ed028..4c66e0ab 100644 --- a/absl/synchronization/blocking_counter.h +++ b/absl/synchronization/blocking_counter.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/blocking_counter_test.cc b/absl/synchronization/blocking_counter_test.cc index e8223f84..c63e3392 100644 --- a/absl/synchronization/blocking_counter_test.cc +++ b/absl/synchronization/blocking_counter_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/create_thread_identity.cc b/absl/synchronization/internal/create_thread_identity.cc index 60be25c9..6e93605d 100644 --- a/absl/synchronization/internal/create_thread_identity.cc +++ b/absl/synchronization/internal/create_thread_identity.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/create_thread_identity.h b/absl/synchronization/internal/create_thread_identity.h index 1bb87dee..b2525b72 100644 --- a/absl/synchronization/internal/create_thread_identity.h +++ b/absl/synchronization/internal/create_thread_identity.h @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/absl/synchronization/internal/graphcycles.cc b/absl/synchronization/internal/graphcycles.cc index d3878de2..0c8c7564 100644 --- a/absl/synchronization/internal/graphcycles.cc +++ b/absl/synchronization/internal/graphcycles.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/graphcycles.h b/absl/synchronization/internal/graphcycles.h index 2e6686a4..e5bde007 100644 --- a/absl/synchronization/internal/graphcycles.h +++ b/absl/synchronization/internal/graphcycles.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/graphcycles_benchmark.cc b/absl/synchronization/internal/graphcycles_benchmark.cc index a239c25c..54823e0b 100644 --- a/absl/synchronization/internal/graphcycles_benchmark.cc +++ b/absl/synchronization/internal/graphcycles_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/graphcycles_test.cc b/absl/synchronization/internal/graphcycles_test.cc index 9a85b390..58e8477b 100644 --- a/absl/synchronization/internal/graphcycles_test.cc +++ b/absl/synchronization/internal/graphcycles_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/kernel_timeout.h b/absl/synchronization/internal/kernel_timeout.h index 9e1eed75..543c4a03 100644 --- a/absl/synchronization/internal/kernel_timeout.h +++ b/absl/synchronization/internal/kernel_timeout.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/mutex_nonprod.cc b/absl/synchronization/internal/mutex_nonprod.cc index 45c60326..267deaff 100644 --- a/absl/synchronization/internal/mutex_nonprod.cc +++ b/absl/synchronization/internal/mutex_nonprod.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/per_thread_sem.cc b/absl/synchronization/internal/per_thread_sem.cc index caa2baf6..d22539dc 100644 --- a/absl/synchronization/internal/per_thread_sem.cc +++ b/absl/synchronization/internal/per_thread_sem.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/per_thread_sem.h b/absl/synchronization/internal/per_thread_sem.h index 678b69e4..d373f63b 100644 --- a/absl/synchronization/internal/per_thread_sem.h +++ b/absl/synchronization/internal/per_thread_sem.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/per_thread_sem_test.cc b/absl/synchronization/internal/per_thread_sem_test.cc index 8a318a51..dba72390 100644 --- a/absl/synchronization/internal/per_thread_sem_test.cc +++ b/absl/synchronization/internal/per_thread_sem_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/thread_pool.h b/absl/synchronization/internal/thread_pool.h index c753a68d..7f458f5a 100644 --- a/absl/synchronization/internal/thread_pool.h +++ b/absl/synchronization/internal/thread_pool.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/waiter.cc b/absl/synchronization/internal/waiter.cc index 768c5208..bab6d1a1 100644 --- a/absl/synchronization/internal/waiter.cc +++ b/absl/synchronization/internal/waiter.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/internal/waiter.h b/absl/synchronization/internal/waiter.h index 23166f4b..66b4bebf 100644 --- a/absl/synchronization/internal/waiter.h +++ b/absl/synchronization/internal/waiter.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/lifetime_test.cc b/absl/synchronization/lifetime_test.cc index 8b168e21..0279c8f8 100644 --- a/absl/synchronization/lifetime_test.cc +++ b/absl/synchronization/lifetime_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index 40ab7d22..f4ed0d00 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 4b65e92c..cf0f86dc 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/mutex_benchmark.cc b/absl/synchronization/mutex_benchmark.cc index 2652bb97..ab188001 100644 --- a/absl/synchronization/mutex_benchmark.cc +++ b/absl/synchronization/mutex_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc index 92fcd53d..53c1f744 100644 --- a/absl/synchronization/mutex_test.cc +++ b/absl/synchronization/mutex_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/notification.cc b/absl/synchronization/notification.cc index cdcbc134..53ace008 100644 --- a/absl/synchronization/notification.cc +++ b/absl/synchronization/notification.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/notification.h b/absl/synchronization/notification.h index f95f4d14..19f51de7 100644 --- a/absl/synchronization/notification.h +++ b/absl/synchronization/notification.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/synchronization/notification_test.cc b/absl/synchronization/notification_test.cc index 95bde0bd..059d4cd2 100644 --- a/absl/synchronization/notification_test.cc +++ b/absl/synchronization/notification_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel index 578dc917..a94be655 100644 --- a/absl/time/BUILD.bazel +++ b/absl/time/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/time/CMakeLists.txt b/absl/time/CMakeLists.txt index db60e712..d67a486d 100644 --- a/absl/time/CMakeLists.txt +++ b/absl/time/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/time/civil_time.cc b/absl/time/civil_time.cc index c7ba8916..7527fc11 100644 --- a/absl/time/civil_time.cc +++ b/absl/time/civil_time.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/civil_time.h b/absl/time/civil_time.h index fd7f1e85..f231e4f8 100644 --- a/absl/time/civil_time.h +++ b/absl/time/civil_time.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/civil_time_benchmark.cc b/absl/time/civil_time_benchmark.cc index f30f636d..40869835 100644 --- a/absl/time/civil_time_benchmark.cc +++ b/absl/time/civil_time_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/civil_time_test.cc b/absl/time/civil_time_test.cc index dc83d7a9..b8d57135 100644 --- a/absl/time/civil_time_test.cc +++ b/absl/time/civil_time_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/clock.cc b/absl/time/clock.cc index 4863f643..fa0ed34d 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/clock.h b/absl/time/clock.h index 3753d4ee..bb52e4f6 100644 --- a/absl/time/clock.h +++ b/absl/time/clock.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/clock_benchmark.cc b/absl/time/clock_benchmark.cc index 3d3cd9d5..a69fe00b 100644 --- a/absl/time/clock_benchmark.cc +++ b/absl/time/clock_benchmark.cc @@ -3,7 +3,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/clock_test.cc b/absl/time/clock_test.cc index 707166d0..4bcfc6bc 100644 --- a/absl/time/clock_test.cc +++ b/absl/time/clock_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/duration.cc b/absl/time/duration.cc index 7d4af8c7..be4ef2ea 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -749,7 +749,7 @@ void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) { } // namespace -// From Go's doc at http://golang.org/pkg/time/#Duration.String +// From Go's doc at https://golang.org/pkg/time/#Duration.String // [FormatDuration] returns a string representing the duration in the // form "72h3m0.5s". Leading zero units are omitted. As a special // case, durations less than one second format use a smaller unit @@ -855,8 +855,8 @@ bool ConsumeDurationUnit(const char** start, Duration* unit) { } // namespace -// From Go's doc at http://golang.org/pkg/time/#ParseDuration -// [ParseDuration] parses a duration string. A duration string is +// From Go's doc at https://golang.org/pkg/time/#ParseDuration +// [ParseDuration] parses a duration string. A duration string is // a possibly signed sequence of decimal numbers, each with optional // fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". // Valid time units are "ns", "us" "ms", "s", "m", "h". diff --git a/absl/time/duration_benchmark.cc b/absl/time/duration_benchmark.cc index f5fcdfb8..83a836c8 100644 --- a/absl/time/duration_benchmark.cc +++ b/absl/time/duration_benchmark.cc @@ -3,7 +3,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc index 6dc307a9..e3cede6e 100644 --- a/absl/time/duration_test.cc +++ b/absl/time/duration_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/format.cc b/absl/time/format.cc index a3671510..d6ca8600 100644 --- a/absl/time/format.cc +++ b/absl/time/format.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/format_benchmark.cc b/absl/time/format_benchmark.cc index 766f1b39..249c51d8 100644 --- a/absl/time/format_benchmark.cc +++ b/absl/time/format_benchmark.cc @@ -3,7 +3,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/format_test.cc b/absl/time/format_test.cc index 46b972e6..4a1f1aa2 100644 --- a/absl/time/format_test.cc +++ b/absl/time/format_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/internal/get_current_time_chrono.inc b/absl/time/internal/get_current_time_chrono.inc index cf884a10..5180230d 100644 --- a/absl/time/internal/get_current_time_chrono.inc +++ b/absl/time/internal/get_current_time_chrono.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/internal/test_util.cc b/absl/time/internal/test_util.cc index 4483f2a9..59166a7c 100644 --- a/absl/time/internal/test_util.cc +++ b/absl/time/internal/test_util.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/internal/test_util.h b/absl/time/internal/test_util.h index d9940293..d7319ea8 100644 --- a/absl/time/internal/test_util.h +++ b/absl/time/internal/test_util.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/time.cc b/absl/time/time.cc index ac2c8a83..799bf859 100644 --- a/absl/time/time.cc +++ b/absl/time/time.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/time.h b/absl/time/time.h index 45df1fc7..fef305c5 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/time_benchmark.cc b/absl/time/time_benchmark.cc index 9bbed6f8..99e62799 100644 --- a/absl/time/time_benchmark.cc +++ b/absl/time/time_benchmark.cc @@ -3,7 +3,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc index 4d710709..74148d58 100644 --- a/absl/time/time_test.cc +++ b/absl/time/time_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/time/time_zone_test.cc b/absl/time/time_zone_test.cc index 43d91904..8f1e74ac 100644 --- a/absl/time/time_zone_test.cc +++ b/absl/time/time_zone_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel index 2e490009..7da00030 100644 --- a/absl/types/BUILD.bazel +++ b/absl/types/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt index 05097d9e..8afde466 100644 --- a/absl/types/CMakeLists.txt +++ b/absl/types/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/types/any.h b/absl/types/any.h index a973c6da..e750f485 100644 --- a/absl/types/any.h +++ b/absl/types/any.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/any_exception_safety_test.cc b/absl/types/any_exception_safety_test.cc index f9dd8c48..00d0fb72 100644 --- a/absl/types/any_exception_safety_test.cc +++ b/absl/types/any_exception_safety_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/any_test.cc b/absl/types/any_test.cc index 115e78df..a6351bf9 100644 --- a/absl/types/any_test.cc +++ b/absl/types/any_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/bad_any_cast.cc b/absl/types/bad_any_cast.cc index 2e2fd29a..505919a5 100644 --- a/absl/types/bad_any_cast.cc +++ b/absl/types/bad_any_cast.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/bad_any_cast.h b/absl/types/bad_any_cast.h index 60390132..8d020ede 100644 --- a/absl/types/bad_any_cast.h +++ b/absl/types/bad_any_cast.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/bad_optional_access.cc b/absl/types/bad_optional_access.cc index 55870776..a791c7c2 100644 --- a/absl/types/bad_optional_access.cc +++ b/absl/types/bad_optional_access.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/bad_optional_access.h b/absl/types/bad_optional_access.h index c6c27460..add5c452 100644 --- a/absl/types/bad_optional_access.h +++ b/absl/types/bad_optional_access.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/bad_variant_access.cc b/absl/types/bad_variant_access.cc index d27d7756..a4325c8d 100644 --- a/absl/types/bad_variant_access.cc +++ b/absl/types/bad_variant_access.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/bad_variant_access.h b/absl/types/bad_variant_access.h index e7355a5a..637db435 100644 --- a/absl/types/bad_variant_access.h +++ b/absl/types/bad_variant_access.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h index a0ab1e8f..4926b321 100644 --- a/absl/types/internal/variant.h +++ b/absl/types/internal/variant.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/optional.cc b/absl/types/optional.cc index ef272904..44ff8294 100644 --- a/absl/types/optional.cc +++ b/absl/types/optional.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/optional.h b/absl/types/optional.h index d800ca68..0c1213f4 100644 --- a/absl/types/optional.h +++ b/absl/types/optional.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/optional_exception_safety_test.cc b/absl/types/optional_exception_safety_test.cc index d117ee51..aaf8ebcd 100644 --- a/absl/types/optional_exception_safety_test.cc +++ b/absl/types/optional_exception_safety_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc index cdbf1404..b93aa98e 100644 --- a/absl/types/optional_test.cc +++ b/absl/types/optional_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/span.h b/absl/types/span.h index a445f7af..bce18ebc 100644 --- a/absl/types/span.h +++ b/absl/types/span.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/span_test.cc b/absl/types/span_test.cc index ae71ebc2..294229ea 100644 --- a/absl/types/span_test.cc +++ b/absl/types/span_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/variant.h b/absl/types/variant.h index 48c5d7bf..9652e3b9 100644 --- a/absl/types/variant.h +++ b/absl/types/variant.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/variant_benchmark.cc b/absl/types/variant_benchmark.cc index 99658ac7..a5f52164 100644 --- a/absl/types/variant_benchmark.cc +++ b/absl/types/variant_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/variant_exception_safety_test.cc b/absl/types/variant_exception_safety_test.cc index 82425dbd..086fcff0 100644 --- a/absl/types/variant_exception_safety_test.cc +++ b/absl/types/variant_exception_safety_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc index c18cb77a..9df702df 100644 --- a/absl/types/variant_test.cc +++ b/absl/types/variant_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, diff --git a/absl/utility/CMakeLists.txt b/absl/utility/CMakeLists.txt index 7fe34a5b..e1edd19a 100644 --- a/absl/utility/CMakeLists.txt +++ b/absl/utility/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# 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, diff --git a/absl/utility/utility.h b/absl/utility/utility.h index 741b1f81..62ce6f3a 100644 --- a/absl/utility/utility.h +++ b/absl/utility/utility.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, @@ -32,8 +32,8 @@ // // References: // -// http://en.cppreference.com/w/cpp/utility/integer_sequence -// http://en.cppreference.com/w/cpp/utility/apply +// https://en.cppreference.com/w/cpp/utility/integer_sequence +// https://en.cppreference.com/w/cpp/utility/apply // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html // diff --git a/absl/utility/utility_test.cc b/absl/utility/utility_test.cc index 7f425fc7..5a4972b6 100644 --- a/absl/utility/utility_test.cc +++ b/absl/utility/utility_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// 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, -- cgit v1.2.3 From 436ba6c4a0ea3a06eca6e055f9c8d296bf3bae12 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 14 May 2019 10:53:39 -0700 Subject: Export of internal Abseil changes. -- 22fceefcf070a0cf89bf1846bee16a9d36ad4161 by Derek Mauro : Use function static for once initialization of flag registry. This is a workaround for the MSVC debug constexpr initialization issue in absl::once_flag. GitHub #304 PiperOrigin-RevId: 248169007 -- 97bbe6a5233802b61e758c55f7ba8926539cc4ca by Chris Kennelly : Internal change PiperOrigin-RevId: 248139347 -- e72640ee079b9fa44e2c7f925fa0a608bcfea515 by Derek Mauro : Re-write flags config. It doesn't have to be written in the convoluted way it currently is in the opensource-only code path. PiperOrigin-RevId: 248010502 -- 2a72552511b8086c78cb43012c1644e519b3807e by Abseil Team : Handle pthread_getschedparam() failure. Log an error message if pthread_getschedparam() fails. In Android's Media Framework, libminijail (which I believe is a sandbox) aborts the process if pthread_getschedparam() is called: media.swcodec: libminijail[7526]: blocked syscall: sched_getparam ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /system/bin/tombstoned: received crash request for pid 7526 Although this CL cannot handle that extreme failure mode, it handles an error return from pthread_getschedparam() and won't use the uninitialized param.sched_priority value in that case. PiperOrigin-RevId: 247999953 -- bb154a92be37987d00d652c7c792594f2f515d83 by Abseil Team : Allow intrinsic int128 to be set for __aarch64__ targets. PiperOrigin-RevId: 247977594 GitOrigin-RevId: 22fceefcf070a0cf89bf1846bee16a9d36ad4161 Change-Id: I1f7ccfd82eb71446277a8e6f542fe835ac173d71 --- absl/base/BUILD.bazel | 2 +- absl/base/config.h | 4 +-- absl/flags/BUILD.bazel | 14 ++++++++++ absl/flags/CMakeLists.txt | 12 ++++++++ absl/flags/config.h | 34 ++++++++++------------- absl/flags/config_test.cc | 61 +++++++++++++++++++++++++++++++++++++++++ absl/flags/internal/registry.cc | 18 ++---------- absl/synchronization/mutex.cc | 14 ++++++---- 8 files changed, 114 insertions(+), 45 deletions(-) create mode 100644 absl/flags/config_test.cc (limited to 'absl/base/config.h') diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 317452da..c6f0e4d6 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -18,9 +18,9 @@ load( "//absl:copts/configure_copts.bzl", "ABSL_DEFAULT_COPTS", "ABSL_DEFAULT_LINKOPTS", - "ABSL_TEST_COPTS", "ABSL_EXCEPTIONS_FLAG", "ABSL_EXCEPTIONS_FLAG_LINKOPTS", + "ABSL_TEST_COPTS", ) package(default_visibility = ["//visibility:public"]) diff --git a/absl/base/config.h b/absl/base/config.h index 3b81e269..2a14fe74 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -191,15 +191,13 @@ // * On Clang: // * Building using Clang for Windows, where the Clang runtime library has // 128-bit support only on LP64 architectures, but Windows is LLP64. -// * Building for aarch64, where __int128 exists but has exhibits a sporadic -// compiler crashing bug. // * On Nvidia's nvcc: // * nvcc also defines __GNUC__ and __SIZEOF_INT128__, but not all versions // actually support __int128. #ifdef ABSL_HAVE_INTRINSIC_INT128 #error ABSL_HAVE_INTRINSIC_INT128 cannot be directly set #elif defined(__SIZEOF_INT128__) -#if (defined(__clang__) && !defined(_WIN32) && !defined(__aarch64__)) || \ +#if (defined(__clang__) && !defined(_WIN32)) || \ (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \ (defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__)) #define ABSL_HAVE_INTRINSIC_INT128 1 diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 2d868b0a..bb1a7aac 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -219,6 +219,20 @@ cc_test( ], ) +cc_test( + name = "config_test", + size = "small", + srcs = [ + "config_test.cc", + ], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":config", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "flag_test", size = "small", diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt index 284d6279..9e0b441b 100644 --- a/absl/flags/CMakeLists.txt +++ b/absl/flags/CMakeLists.txt @@ -201,6 +201,18 @@ absl_cc_test( gtest_main ) +absl_cc_test( + NAME + flags_config_test + SRCS + "config_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::flags_config + gtest_main +) + absl_cc_test( NAME flags_flag_test diff --git a/absl/flags/config.h b/absl/flags/config.h index a734af46..a9fd97ad 100644 --- a/absl/flags/config.h +++ b/absl/flags/config.h @@ -17,38 +17,32 @@ #define ABSL_FLAGS_CONFIG_H_ // Determine if we should strip string literals from the Flag objects. +// By default we strip string literals on mobile platforms. #if !defined(ABSL_FLAGS_STRIP_NAMES) -// Non-mobile linux platforms don't strip string literals. -#if (defined(__linux__) || defined(__Fuchsia__)) && !defined(__ANDROID__) -#define ABSL_FLAGS_STRIP_NAMES 0 +#if defined(__ANDROID__) +#define ABSL_FLAGS_STRIP_NAMES 1 -// So do Macs (not iOS or embedded Apple platforms). #elif defined(__APPLE__) #include -#if !TARGET_OS_IPHONE && !TARGET_OS_EMBEDDED -#define ABSL_FLAGS_STRIP_NAMES 0 +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +#define ABSL_FLAGS_STRIP_NAMES 1 +#elif defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED +#define ABSL_FLAGS_STRIP_NAMES 1 +#endif // TARGET_OS_* #endif -// And Windows. -#elif defined(_WIN32) -#define ABSL_FLAGS_STRIP_NAMES 0 +#endif // !defined(ABSL_FLAGS_STRIP_NAMES) -// And Myriad. -#elif defined(__myriad2__) +#if !defined(ABSL_FLAGS_STRIP_NAMES) +// If ABSL_FLAGS_STRIP_NAMES wasn't set on the command line or above, +// the default is not to strip. #define ABSL_FLAGS_STRIP_NAMES 0 - #endif -#endif // !defined(ABSL_FLAGS_STRIP_NAMES) -#if ABSL_FLAGS_STRIP_NAMES #if !defined(ABSL_FLAGS_STRIP_HELP) -#define ABSL_FLAGS_STRIP_HELP 1 -#endif -#else -#if !defined(ABSL_FLAGS_STRIP_HELP) -#define ABSL_FLAGS_STRIP_HELP 0 -#endif +// By default, if we strip names, we also strip help. +#define ABSL_FLAGS_STRIP_HELP ABSL_FLAGS_STRIP_NAMES #endif #endif // ABSL_FLAGS_CONFIG_H_ diff --git a/absl/flags/config_test.cc b/absl/flags/config_test.cc new file mode 100644 index 00000000..63899866 --- /dev/null +++ b/absl/flags/config_test.cc @@ -0,0 +1,61 @@ +// 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. + +#include "absl/flags/config.h" + +#ifdef __APPLE__ +#include +#endif + +#include "gtest/gtest.h" + +#ifndef ABSL_FLAGS_STRIP_NAMES +#error ABSL_FLAGS_STRIP_NAMES is not defined +#endif + +#ifndef ABSL_FLAGS_STRIP_HELP +#error ABSL_FLAGS_STRIP_HELP is not defined +#endif + +namespace { + +// Test that ABSL_FLAGS_STRIP_NAMES and ABSL_FLAGS_STRIP_HELP are configured how +// we expect them to be configured by default. If you override this +// configuration, this test will fail, but the code should still be safe to use. +TEST(FlagsConfigTest, Test) { +#if defined(__ANDROID__) + EXPECT_EQ(ABSL_FLAGS_STRIP_NAMES, 1); + EXPECT_EQ(ABSL_FLAGS_STRIP_HELP, 1); +#elif defined(__myriad2__) + EXPECT_EQ(ABSL_FLAGS_STRIP_NAMES, 0); + EXPECT_EQ(ABSL_FLAGS_STRIP_HELP, 0); +#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE + EXPECT_EQ(ABSL_FLAGS_STRIP_NAMES, 1); + EXPECT_EQ(ABSL_FLAGS_STRIP_HELP, 1); +#elif defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED + EXPECT_EQ(ABSL_FLAGS_STRIP_NAMES, 1); + EXPECT_EQ(ABSL_FLAGS_STRIP_HELP, 1); +#elif defined(__APPLE__) + EXPECT_EQ(ABSL_FLAGS_STRIP_NAMES, 0); + EXPECT_EQ(ABSL_FLAGS_STRIP_HELP, 0); +#elif defined(_WIN32) + EXPECT_EQ(ABSL_FLAGS_STRIP_NAMES, 0); + EXPECT_EQ(ABSL_FLAGS_STRIP_HELP, 0); +#elif defined(__linux__) + EXPECT_EQ(ABSL_FLAGS_STRIP_NAMES, 0); + EXPECT_EQ(ABSL_FLAGS_STRIP_HELP, 0); +#endif +} + +} // namespace diff --git a/absl/flags/internal/registry.cc b/absl/flags/internal/registry.cc index 435c5b0b..e52cbb68 100644 --- a/absl/flags/internal/registry.cc +++ b/absl/flags/internal/registry.cc @@ -15,7 +15,6 @@ #include "absl/flags/internal/registry.h" -#include "absl/base/call_once.h" #include "absl/base/dynamic_annotations.h" #include "absl/base/internal/raw_logging.h" #include "absl/flags/config.h" @@ -151,12 +150,6 @@ class FlagRegistry { FlagPtrMap flag_ptr_map_; - static FlagRegistry* global_registry_; // a singleton registry - - static absl::once_flag global_registry_once_; - - static void InitGlobalRegistry(); - absl::Mutex lock_; // Disallow @@ -164,16 +157,9 @@ class FlagRegistry { FlagRegistry& operator=(const FlagRegistry&); }; -// Get the singleton FlagRegistry object -FlagRegistry* FlagRegistry::global_registry_ = nullptr; -absl::once_flag FlagRegistry::global_registry_once_; - -void FlagRegistry::InitGlobalRegistry() { global_registry_ = new FlagRegistry; } - FlagRegistry* FlagRegistry::GlobalRegistry() { - absl::call_once(global_registry_once_, &InitGlobalRegistry); - - return global_registry_; + static FlagRegistry* global_registry = new FlagRegistry; + return global_registry; } namespace { diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index 3e8033a0..76bd307a 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc @@ -901,11 +901,15 @@ static PerThreadSynch *Enqueue(PerThreadSynch *head, // base_internal::CycleClock::Now() is 0.5%. int policy; struct sched_param param; - pthread_getschedparam(pthread_self(), &policy, ¶m); - s->priority = param.sched_priority; - s->next_priority_read_cycles = - now_cycles + - static_cast(base_internal::CycleClock::Frequency()); + const int err = pthread_getschedparam(pthread_self(), &policy, ¶m); + if (err != 0) { + ABSL_RAW_LOG(ERROR, "pthread_getschedparam failed: %d", err); + } else { + s->priority = param.sched_priority; + s->next_priority_read_cycles = + now_cycles + + static_cast(base_internal::CycleClock::Frequency()); + } } if (s->priority > head->priority) { // s's priority is above head's // try to put s in priority-fifo order, or failing that at the front. -- cgit v1.2.3 From 8f11724067248acc330b4d1f12f0c76d03f2cfb1 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 13 Jun 2019 09:14:42 -0700 Subject: Export of internal Abseil changes. -- fc61fc3822d414a1abda906a81208d2667195de3 by Abseil Team : Clarify documentation relating to the output of the various printing functions. PiperOrigin-RevId: 253041344 -- 06cb414d1006cd89e38b381d52763b048909d69a by Jorg Brown : Change absl::container_internal::CompressedTuple to instantiate its internal Storage class with the name of the type it's holding, rather than the name of the Tuple. This is not an externally-visible change, other than less compiler memory is used and less debug information is generated. PiperOrigin-RevId: 252940185 -- 33b3f3ed6037eac7d1b7989a3641370e92beaeb9 by Jorg Brown : Change absl::container_internal::CompressedTuple to instantiate its internal Storage class with the name of the type it's holding, rather than the name of the Tuple. This is not an externally-visible change, other than less compiler memory is used and less debug information is generated. PiperOrigin-RevId: 252902091 -- 88595f4e7d6ac57bebdc9811045867f5d7477b5b by Abseil Team : Unset thread_local/__thread support for Emscripten. PiperOrigin-RevId: 252706297 -- cabd1715d873dc457271940335c764e62defb952 by Derek Mauro : Rollback LLVM and Bazel version due to intermittent network failures downloading from GitHub PiperOrigin-RevId: 252661245 GitOrigin-RevId: fc61fc3822d414a1abda906a81208d2667195de3 Change-Id: I4c30995a2db7acef19415ad519259131584db261 --- absl/base/config.h | 7 +++++++ absl/copts/GENERATED_AbseilCopts.cmake | 2 ++ absl/copts/GENERATED_copts.bzl | 2 ++ absl/copts/copts.py | 2 ++ absl/strings/str_cat.h | 3 ++- absl/strings/str_format.h | 11 +++++++++-- absl/strings/substitute.h | 7 +++++-- ci/linux_clang-latest_libcxx_asan_bazel.sh | 2 +- ci/linux_clang-latest_libcxx_bazel.sh | 2 +- ci/linux_clang-latest_libcxx_tsan_bazel.sh | 2 +- ci/linux_clang-latest_libstdcxx_bazel.sh | 2 +- 11 files changed, 33 insertions(+), 9 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index 2a14fe74..f12f84fd 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -181,6 +181,13 @@ #endif #endif // defined(__ANDROID__) && defined(__clang__) +// Emscripten doesn't yet support `thread_local` or `__thread`. +// https://github.com/emscripten-core/emscripten/issues/3502 +#if defined(__EMSCRIPTEN__) +#undef ABSL_HAVE_TLS +#undef ABSL_HAVE_THREAD_LOCAL +#endif // defined(__EMSCRIPTEN__) + // ABSL_HAVE_INTRINSIC_INT128 // // Checks whether the __int128 compiler extension for a 128-bit integral type is diff --git a/absl/copts/GENERATED_AbseilCopts.cmake b/absl/copts/GENERATED_AbseilCopts.cmake index 927ef290..c4948d42 100644 --- a/absl/copts/GENERATED_AbseilCopts.cmake +++ b/absl/copts/GENERATED_AbseilCopts.cmake @@ -77,6 +77,7 @@ list(APPEND ABSL_CLANG_CL_TEST_FLAGS "-Wno-unused-template" "-Wno-used-but-marked-unused" "-Wno-zero-as-null-pointer-constant" + "-Wno-gnu-include-next" "-Wno-gnu-zero-variadic-macro-arguments" ) @@ -180,6 +181,7 @@ list(APPEND ABSL_LLVM_TEST_FLAGS "-Wno-unused-template" "-Wno-used-but-marked-unused" "-Wno-zero-as-null-pointer-constant" + "-Wno-gnu-include-next" "-Wno-gnu-zero-variadic-macro-arguments" ) diff --git a/absl/copts/GENERATED_copts.bzl b/absl/copts/GENERATED_copts.bzl index 58bdfef9..422b3a9b 100644 --- a/absl/copts/GENERATED_copts.bzl +++ b/absl/copts/GENERATED_copts.bzl @@ -78,6 +78,7 @@ ABSL_CLANG_CL_TEST_FLAGS = [ "-Wno-unused-template", "-Wno-used-but-marked-unused", "-Wno-zero-as-null-pointer-constant", + "-Wno-gnu-include-next", "-Wno-gnu-zero-variadic-macro-arguments", ] @@ -181,6 +182,7 @@ ABSL_LLVM_TEST_FLAGS = [ "-Wno-unused-template", "-Wno-used-but-marked-unused", "-Wno-zero-as-null-pointer-constant", + "-Wno-gnu-include-next", "-Wno-gnu-zero-variadic-macro-arguments", ] diff --git a/absl/copts/copts.py b/absl/copts/copts.py index 4594fda2..5bede34c 100644 --- a/absl/copts/copts.py +++ b/absl/copts/copts.py @@ -105,6 +105,8 @@ LLVM_TEST_DISABLE_WARNINGS_FLAGS = [ "-Wno-unused-template", "-Wno-used-but-marked-unused", "-Wno-zero-as-null-pointer-constant", + # For a libc++ bug fixed in r357267 + "-Wno-gnu-include-next", # gtest depends on this GNU extension being offered. "-Wno-gnu-zero-variadic-macro-arguments", ] diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h index 559ee0aa..a99aac01 100644 --- a/absl/strings/str_cat.h +++ b/absl/strings/str_cat.h @@ -37,7 +37,8 @@ // attempt to pass ':' instead of ":" might result in a 58 ending up in your // result. // -// Bools convert to "0" or "1". +// Bools convert to "0" or "1". Pointers to types other than `char *` are not +// valid inputs. No output is generated for null `char *` pointers. // // Floating point numbers are formatted with six-digit precision, which is // the default for "std::cout <<" or printf "%g" (the same as "%.6g"). diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index da3208e1..0b93c288 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -20,7 +20,8 @@ // The `str_format` library is a typesafe replacement for the family of // `printf()` string formatting routines within the `` standard library // header. Like the `printf` family, the `str_format` uses a "format string" to -// perform argument substitutions based on types. +// perform argument substitutions based on types. See the `FormatSpec` section +// below for format string documentation. // // Example: // @@ -67,6 +68,7 @@ // In addition, the `str_format` library provides extension points for // augmenting formatting to new types. These extensions are fully documented // within the `str_format_extension.h` header file. + #ifndef ABSL_STRINGS_STR_FORMAT_H_ #define ABSL_STRINGS_STR_FORMAT_H_ @@ -211,6 +213,11 @@ class FormatCountCapture { // written to this point. The resulting value must be captured within an // `absl::FormatCountCapture` type. // +// Implementation-defined behavior: +// * A null pointer provided to "%s" or "%p" is output as "(nil)". +// * A non-null pointer provided to "%p" is output in hex as if by %#x or +// %#lx. +// // NOTE: `o`, `x\X` and `u` will convert signed values to their unsigned // counterpart before formatting. // @@ -226,7 +233,7 @@ class FormatCountCapture { // "%e", .01 -> "1.00000e-2" // "%a", -3.0 -> "-0x1.8p+1" // "%g", .01 -> "1e-2" -// "%p", *int -> "0x7ffdeb6ad2a4" +// "%p", (void*)&value -> "0x7ffdeb6ad2a4" // // int n = 0; // std::string s = absl::StrFormat( diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h index 32dec30b..233e9dcf 100644 --- a/absl/strings/substitute.h +++ b/absl/strings/substitute.h @@ -35,10 +35,13 @@ // and single digit positional ids to indicate which substitution arguments to // use at that location within the format string. // +// A '$$' sequence in the format string causes a literal '$' character to be +// output. +// // Example 1: -// std::string s = Substitute("$1 purchased $0 $2. Thanks $1!", +// std::string s = Substitute("$1 purchased $0 $2 for $$10. Thanks $1!", // 5, "Bob", "Apples"); -// EXPECT_EQ("Bob purchased 5 Apples. Thanks Bob!", s); +// EXPECT_EQ("Bob purchased 5 Apples for $10. Thanks Bob!", s); // // Example 2: // std::string s = "Hi. "; diff --git a/ci/linux_clang-latest_libcxx_asan_bazel.sh b/ci/linux_clang-latest_libcxx_asan_bazel.sh index a175810a..113acdbe 100755 --- a/ci/linux_clang-latest_libcxx_asan_bazel.sh +++ b/ci/linux_clang-latest_libcxx_asan_bazel.sh @@ -32,7 +32,7 @@ if [ -z ${COMPILATION_MODE:-} ]; then COMPILATION_MODE="fastbuild opt" fi -readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190610" +readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190508" # USE_BAZEL_CACHE=1 only works on Kokoro. # Without access to the credentials this won't work. diff --git a/ci/linux_clang-latest_libcxx_bazel.sh b/ci/linux_clang-latest_libcxx_bazel.sh index 844fff5d..f32cbef7 100755 --- a/ci/linux_clang-latest_libcxx_bazel.sh +++ b/ci/linux_clang-latest_libcxx_bazel.sh @@ -32,7 +32,7 @@ if [ -z ${COMPILATION_MODE:-} ]; then COMPILATION_MODE="fastbuild opt" fi -readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190610" +readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190508" # USE_BAZEL_CACHE=1 only works on Kokoro. # Without access to the credentials this won't work. diff --git a/ci/linux_clang-latest_libcxx_tsan_bazel.sh b/ci/linux_clang-latest_libcxx_tsan_bazel.sh index b856b4e6..c4edd198 100755 --- a/ci/linux_clang-latest_libcxx_tsan_bazel.sh +++ b/ci/linux_clang-latest_libcxx_tsan_bazel.sh @@ -32,7 +32,7 @@ if [ -z ${COMPILATION_MODE:-} ]; then COMPILATION_MODE="fastbuild opt" fi -readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190610" +readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190508" # USE_BAZEL_CACHE=1 only works on Kokoro. # Without access to the credentials this won't work. diff --git a/ci/linux_clang-latest_libstdcxx_bazel.sh b/ci/linux_clang-latest_libstdcxx_bazel.sh index 320b7cdf..7bbecd6f 100755 --- a/ci/linux_clang-latest_libstdcxx_bazel.sh +++ b/ci/linux_clang-latest_libstdcxx_bazel.sh @@ -32,7 +32,7 @@ if [ -z ${COMPILATION_MODE:-} ]; then COMPILATION_MODE="fastbuild opt" fi -readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190610" +readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_clang-latest:20190508" # USE_BAZEL_CACHE=1 only works on Kokoro. # Without access to the credentials this won't work. -- cgit v1.2.3 From 5fc0bf69e7b78d35e6d8621db994f7f307a83d59 Mon Sep 17 00:00:00 2001 From: Joe Sylve Date: Tue, 25 Jun 2019 16:57:48 -0500 Subject: Fixed ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE check --- absl/base/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index f12f84fd..406a931f 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -375,7 +375,7 @@ // https://github.com/abseil/abseil-cpp/issues/207 and // https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes #if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \ - defined(__MAC_OS_X_VERSION_MIN_REQUIRED__) && \ + defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400 #define ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE 1 #else -- cgit v1.2.3 From f3840bc5e33ce4932e35986cf3718450c6f02af2 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 18 Jul 2019 15:07:49 -0700 Subject: Export of internal Abseil changes. -- dcff7cc4eb3837d39d1e083cbf1d4f082054cbf6 by Laramie Leavitt : Add default and fallback modes for SaltedSeedSeq::generate(). SeedSeq::generate will often be called with contiguous ranges of uint32_t. Detect this case and use the currently direct code paths to handle it. Otherwise use a fallback mechanism which does an additional copy. PiperOrigin-RevId: 258853656 -- 59ec88845ac2ee6567c493021b54385940d66762 by Gennadiy Rozental : Internal change PiperOrigin-RevId: 258822137 -- eb2d1ab21f6f94c24c51c1cd3719846be259e8e7 by Abseil Team : Add iOS version 11 to the mix of Apple OS versions that have various C++17 header files but do not support them. PiperOrigin-RevId: 258820405 -- 452cea3e13b29797b2c385d7c6da7613d36bdc45 by Gennadiy Rozental : Internal change PiperOrigin-RevId: 258802436 GitOrigin-RevId: dcff7cc4eb3837d39d1e083cbf1d4f082054cbf6 Change-Id: I2261cb58e142eb15017ef646a56710dd64f06496 --- absl/base/config.h | 22 ++++++---- absl/flags/flag.h | 21 +++++---- absl/flags/internal/registry.cc | 80 +++------------------------------- absl/flags/internal/registry.h | 3 +- absl/random/internal/salted_seed_seq.h | 63 +++++++++++++++----------- 5 files changed, 67 insertions(+), 122 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index 406a931f..692738e3 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -370,16 +370,20 @@ #error "absl endian detection needs to be set up for your compiler" #endif -// MacOS 10.13 doesn't let you use , , or even though -// the headers exist and are publicly noted to work. See +// MacOS 10.13 and iOS 10.11 don't let you use , , or +// even though the headers exist and are publicly noted to work. See // https://github.com/abseil/abseil-cpp/issues/207 and // https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes +// libc++ spells out the availability requirements in the file +// llvm-project/libcxx/include/__config. #if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \ - defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400 -#define ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE 1 + ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 101200)) +#define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 1 #else -#define ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE 0 +#define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 0 #endif // ABSL_HAVE_STD_ANY @@ -391,7 +395,7 @@ #ifdef __has_include #if __has_include() && __cplusplus >= 201703L && \ - !ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE + !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE #define ABSL_HAVE_STD_ANY 1 #endif #endif @@ -405,7 +409,7 @@ #ifdef __has_include #if __has_include() && __cplusplus >= 201703L && \ - !ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE + !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE #define ABSL_HAVE_STD_OPTIONAL 1 #endif #endif @@ -419,7 +423,7 @@ #ifdef __has_include #if __has_include() && __cplusplus >= 201703L && \ - !ABSL_INTERNAL_MACOS_CXX17_TYPES_UNAVAILABLE + !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE #define ABSL_HAVE_STD_VARIANT 1 #endif #endif diff --git a/absl/flags/flag.h b/absl/flags/flag.h index c70023ab..6c9f4876 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -216,17 +216,16 @@ void SetFlag(absl::Flag* flag, const V& v) { // Note: Name of registrar object is not arbitrary. It is used to "grab" // global name for FLAGS_no symbol, thus preventing the possibility // of defining two flags with names foo and nofoo. -#define ABSL_FLAG_IMPL(Type, name, default_value, help) \ - namespace absl {} \ - ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ - ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help) \ - absl::Flag FLAGS_##name( \ - ABSL_FLAG_IMPL_FLAGNAME(#name), \ - &AbslFlagsWrapHelp##name, \ - ABSL_FLAG_IMPL_FILENAME(), \ - &absl::flags_internal::FlagMarshallingOps, \ - &AbslFlagsInitFlag##name); \ - extern bool FLAGS_no##name; \ +#define ABSL_FLAG_IMPL(Type, name, default_value, help) \ + namespace absl {} \ + ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ + ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help) \ + ABSL_CONST_INIT absl::Flag FLAGS_##name( \ + ABSL_FLAG_IMPL_FLAGNAME(#name), &AbslFlagsWrapHelp##name, \ + ABSL_FLAG_IMPL_FILENAME(), \ + &absl::flags_internal::FlagMarshallingOps, \ + &AbslFlagsInitFlag##name); \ + extern bool FLAGS_no##name; \ bool FLAGS_no##name = ABSL_FLAG_IMPL_REGISTRAR(Type, FLAGS_##name) // ABSL_RETIRED_FLAG diff --git a/absl/flags/internal/registry.cc b/absl/flags/internal/registry.cc index f37871c9..4e5d1106 100644 --- a/absl/flags/internal/registry.cc +++ b/absl/flags/internal/registry.cc @@ -54,53 +54,6 @@ void DestroyFlag(CommandLineFlag* flag) NO_THREAD_SAFETY_ANALYSIS { // the function will acquire it itself if needed. // -------------------------------------------------------------------- -// A map from flag pointer to CommandLineFlag*. Used when registering -// validators. -class FlagPtrMap { - public: - void Register(CommandLineFlag* flag) { - auto& vec = buckets_[BucketForFlag(flag->cur)]; - if (vec.size() == vec.capacity()) { - // Bypass default 2x growth factor with 1.25 so we have fuller vectors. - // This saves 4% memory compared to default growth. - vec.reserve(vec.size() * 1.25 + 0.5); - } - vec.push_back(flag); - } - - CommandLineFlag* FindByPtr(const void* flag_ptr) { - const auto& flag_vector = buckets_[BucketForFlag(flag_ptr)]; - for (CommandLineFlag* entry : flag_vector) { - if (entry->cur == flag_ptr) { - return entry; - } - } - return nullptr; - } - - private: - // Instead of std::map, we use a custom hash table where each bucket stores - // flags in a vector. This reduces memory usage 40% of the memory that would - // have been used by std::map. - // - // kNumBuckets was picked as a large enough prime. As of writing this code, a - // typical large binary has ~8k (old-style) flags, and this would gives - // buckets with roughly 50 elements each. - // - // Note that reads to this hash table are rare: exactly as many as we have - // flags with validators. As of writing, a typical binary only registers 52 - // validated flags. - static constexpr size_t kNumBuckets = 163; - std::vector buckets_[kNumBuckets]; - - static int BucketForFlag(const void* ptr) { - // Modulo a prime is good enough here. On a real program, bucket size stddev - // after registering 8k flags is ~5 (mean size at 51). - return reinterpret_cast(ptr) % kNumBuckets; - } -}; -constexpr size_t FlagPtrMap::kNumBuckets; - class FlagRegistry { public: FlagRegistry() = default; @@ -111,9 +64,7 @@ class FlagRegistry { } // Store a flag in this registry. Takes ownership of *flag. - // If ptr is non-null, the flag can later be found by calling - // FindFlagViaPtrLocked(ptr). - void RegisterFlag(CommandLineFlag* flag, const void* ptr); + void RegisterFlag(CommandLineFlag* flag); void Lock() EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); } void Unlock() UNLOCK_FUNCTION(lock_) { lock_.Unlock(); } @@ -126,9 +77,6 @@ class FlagRegistry { // found or not retired. Does not emit a warning. CommandLineFlag* FindRetiredFlagLocked(absl::string_view name); - // Returns the flag object whose current-value is stored at flag_ptr. - CommandLineFlag* FindFlagViaPtrLocked(const void* flag_ptr); - static FlagRegistry* GlobalRegistry(); // returns a singleton registry private: @@ -142,8 +90,6 @@ class FlagRegistry { using FlagConstIterator = FlagMap::const_iterator; FlagMap flags_; - FlagPtrMap flag_ptr_map_; - absl::Mutex lock_; // Disallow @@ -169,7 +115,7 @@ class FlagRegistryLock { } // namespace -void FlagRegistry::RegisterFlag(CommandLineFlag* flag, const void* ptr) { +void FlagRegistry::RegisterFlag(CommandLineFlag* flag) { FlagRegistryLock registry_lock(this); std::pair ins = flags_.insert(FlagMap::value_type(flag->Name(), flag)); @@ -217,11 +163,6 @@ void FlagRegistry::RegisterFlag(CommandLineFlag* flag, const void* ptr) { // All cases above are fatal, except for the retired flags. std::exit(1); } - - if (ptr != nullptr) { - // This must be the first time we're seeing this flag. - flag_ptr_map_.Register(flag); - } } CommandLineFlag* FlagRegistry::FindFlagLocked(absl::string_view name) { @@ -247,10 +188,6 @@ CommandLineFlag* FlagRegistry::FindRetiredFlagLocked(absl::string_view name) { return i->second; } -CommandLineFlag* FlagRegistry::FindFlagViaPtrLocked(const void* flag_ptr) { - return flag_ptr_map_.FindByPtr(flag_ptr); -} - // -------------------------------------------------------------------- // FlagSaver // FlagSaverImpl @@ -430,13 +367,6 @@ CommandLineFlag* FindCommandLineFlag(absl::string_view name) { return registry->FindFlagLocked(name); } -CommandLineFlag* FindCommandLineV1Flag(const void* flag_ptr) { - FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); - FlagRegistryLock frl(registry); - - return registry->FindFlagViaPtrLocked(flag_ptr); -} - CommandLineFlag* FindRetiredFlag(absl::string_view name) { FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); FlagRegistryLock frl(registry); @@ -477,8 +407,8 @@ void GetAllFlags(std::vector* OUTPUT) { // -------------------------------------------------------------------- -bool RegisterCommandLineFlag(CommandLineFlag* flag, const void* ptr) { - FlagRegistry::GlobalRegistry()->RegisterFlag(flag, ptr); +bool RegisterCommandLineFlag(CommandLineFlag* flag) { + FlagRegistry::GlobalRegistry()->RegisterFlag(flag); return true; } @@ -492,7 +422,7 @@ bool Retire(FlagOpFn ops, FlagMarshallingOpFn marshalling_ops, /*filename_arg=*/"RETIRED", ops, marshalling_ops, /*initial_value_gen=*/nullptr, /*retired_arg=*/true, nullptr, nullptr); - FlagRegistry::GlobalRegistry()->RegisterFlag(flag, nullptr); + FlagRegistry::GlobalRegistry()->RegisterFlag(flag); return true; } diff --git a/absl/flags/internal/registry.h b/absl/flags/internal/registry.h index bd141e1e..27566fbf 100644 --- a/absl/flags/internal/registry.h +++ b/absl/flags/internal/registry.h @@ -57,7 +57,6 @@ void FillCommandLineFlagInfo(CommandLineFlag* flag, //----------------------------------------------------------------------------- CommandLineFlag* FindCommandLineFlag(absl::string_view name); -CommandLineFlag* FindCommandLineV1Flag(const void* flag_ptr); CommandLineFlag* FindRetiredFlag(absl::string_view name); // Executes specified visitor for each non-retired flag in the registry. @@ -74,7 +73,7 @@ void GetAllFlags(std::vector* OUTPUT); //----------------------------------------------------------------------------- -bool RegisterCommandLineFlag(CommandLineFlag*, const void* ptr = nullptr); +bool RegisterCommandLineFlag(CommandLineFlag*); //----------------------------------------------------------------------------- // Retired registrations: diff --git a/absl/random/internal/salted_seed_seq.h b/absl/random/internal/salted_seed_seq.h index 3d16cf97..e160f79e 100644 --- a/absl/random/internal/salted_seed_seq.h +++ b/absl/random/internal/salted_seed_seq.h @@ -64,10 +64,15 @@ class SaltedSeedSeq { template void generate(RandomAccessIterator begin, RandomAccessIterator end) { + // The common case is that generate is called with ContiguousIterators + // to uint arrays. Such contiguous memory regions may be optimized, + // which we detect here. + using tag = absl::conditional_t< + (std::is_pointer::value && + std::is_same, uint32_t>::value), + ContiguousAndUint32Tag, DefaultTag>; if (begin != end) { - generate_impl( - std::integral_constant{}, - begin, end); + generate_impl(begin, end, tag{}); } } @@ -79,19 +84,12 @@ class SaltedSeedSeq { size_t size() const { return seq_->size(); } private: - // The common case for generate is that it is called with iterators over a - // 32-bit value buffer. These can be reinterpreted to a uint32_t and we can - // operate on them as such. - template - void generate_impl(std::integral_constant /*is_32bit*/, - RandomAccessIterator begin, RandomAccessIterator end) { - seq_->generate(begin, end); - const uint32_t salt = absl::random_internal::GetSaltMaterial().value_or(0); - auto buffer = absl::MakeSpan(begin, end); - MixIntoSeedMaterial( - absl::MakeConstSpan(&salt, 1), - absl::MakeSpan(reinterpret_cast(buffer.data()), - buffer.size())); + struct ContiguousAndUint32Tag {}; + struct DefaultTag {}; + + // Generate which requires the iterators are contiguous pointers to uint32_t. + void generate_impl(uint32_t* begin, uint32_t* end, ContiguousAndUint32Tag) { + generate_contiguous(absl::MakeSpan(begin, end)); } // The uncommon case for generate is that it is called with iterators over @@ -99,17 +97,32 @@ class SaltedSeedSeq { // case we allocate a temporary 32-bit buffer and then copy-assign back // to the initial inputs. template - void generate_impl(std::integral_constant /*is_32bit*/, - RandomAccessIterator begin, RandomAccessIterator end) { - // Allocate a temporary buffer, seed, and then copy. - absl::InlinedVector data(std::distance(begin, end), 0); - generate_impl(std::integral_constant{}, data.begin(), - data.end()); - std::copy(data.begin(), data.end(), begin); + void generate_impl(RandomAccessIterator begin, RandomAccessIterator end, + DefaultTag) { + return generate_and_copy(std::distance(begin, end), begin); + } + + // Fills the initial seed buffer the underlying SSeq::generate() call, + // mixing in the salt material. + void generate_contiguous(absl::Span buffer) { + seq_->generate(buffer.begin(), buffer.end()); + const uint32_t salt = absl::random_internal::GetSaltMaterial().value_or(0); + MixIntoSeedMaterial(absl::MakeConstSpan(&salt, 1), buffer); + } + + // Allocates a seed buffer of `n` elements, generates the seed, then + // copies the result into the `out` iterator. + template + void generate_and_copy(size_t n, Iterator out) { + // Allocate a temporary buffer, generate, and then copy. + absl::InlinedVector data(n, 0); + generate_contiguous(absl::MakeSpan(data.data(), data.size())); + std::copy(data.begin(), data.end(), out); } - // Because [rand.req.seedseq] is not copy-constructible, copy-assignable nor - // movable so we wrap it with unique pointer to be able to move SaltedSeedSeq. + // Because [rand.req.seedseq] is not required to be copy-constructible, + // copy-assignable nor movable, we wrap it with unique pointer to be able + // to move SaltedSeedSeq. std::unique_ptr seq_; }; -- cgit v1.2.3 From 52e88ee56b72cf32bc66534d942c7398ce481331 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 30 Jul 2019 07:36:25 -0700 Subject: Export of internal Abseil changes. -- 788c948f698afe5998738cbb40b0629668640d73 by Derek Mauro : Add an empty raw_logging_internal library. The raw_logging sources will eventually migrate here. This target will only contain internal sources. Abseil compatibility guidelines require users not depend on internals. https://abseil.io/about/compatibility PiperOrigin-RevId: 260712817 -- 8ea947ec54f47fb02e97597d243cb63aa4c5fe0b by Abseil Team : Fixed an incorrect version number test for optional,etc. availability in iOS. Added tests for watchOS and tvOS. PiperOrigin-RevId: 260490390 -- 53af0544277dc3020b81d16ce110e7bc89f5cf6e by Jorg Brown : Test the error-string path a bit more. PiperOrigin-RevId: 260175886 GitOrigin-RevId: 788c948f698afe5998738cbb40b0629668640d73 Change-Id: I366b73331857dc5a1db843b650c2ba27a69a141e --- absl/base/BUILD.bazel | 9 +++++++++ absl/base/CMakeLists.txt | 9 ++++++++- absl/base/config.h | 9 +++++++-- absl/strings/escaping_test.cc | 11 ++++++++++- 4 files changed, 34 insertions(+), 4 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 1a18f5f7..e825de0c 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -46,6 +46,15 @@ cc_library( deps = [":core_headers"], ) +cc_library( + name = "raw_logging_internal", + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + visibility = [ + "//absl:__subpackages__", + ], +) + cc_library( name = "spinlock_wait", srcs = [ diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 8417556c..9ff80738 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -34,7 +34,14 @@ absl_cc_library( absl::core_headers COPTS ${ABSL_DEFAULT_COPTS} -) +) + +absl_cc_library( + NAME + raw_logging_internal + COPTS + ${ABSL_DEFAULT_COPTS} +) absl_cc_library( NAME diff --git a/absl/base/config.h b/absl/base/config.h index 692738e3..181d840e 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -375,12 +375,17 @@ // https://github.com/abseil/abseil-cpp/issues/207 and // https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes // libc++ spells out the availability requirements in the file -// llvm-project/libcxx/include/__config. +// llvm-project/libcxx/include/__config via the #define +// _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS. #if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \ ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400) || \ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 101200)) + __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 120000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 50000)) #define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 1 #else #define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 0 diff --git a/absl/strings/escaping_test.cc b/absl/strings/escaping_test.cc index 6a633cdc..1967975b 100644 --- a/absl/strings/escaping_test.cc +++ b/absl/strings/escaping_test.cc @@ -72,6 +72,11 @@ TEST(CEscape, EscapeAndUnescape) { EXPECT_TRUE(absl::CUnescape(escaped, &unescaped_str)); EXPECT_EQ(unescaped_str, original); + unescaped_str.erase(); + std::string error; + EXPECT_TRUE(absl::CUnescape(escaped, &unescaped_str, &error)); + EXPECT_EQ(error, ""); + // Check in-place unescaping std::string s = escaped; EXPECT_TRUE(absl::CUnescape(s, &s)); @@ -150,7 +155,8 @@ TEST(CEscape, BasicEscaping) { TEST(Unescape, BasicFunction) { epair tests[] = - {{"\\u0030", "0"}, + {{"", ""}, + {"\\u0030", "0"}, {"\\u00A3", "\xC2\xA3"}, {"\\u22FD", "\xE2\x8B\xBD"}, {"\\U00010000", "\xF0\x90\x80\x80"}, @@ -173,6 +179,9 @@ TEST(Unescape, BasicFunction) { std::string out; EXPECT_FALSE(absl::CUnescape(e, &out, &error)); EXPECT_FALSE(error.empty()); + + out.erase(); + EXPECT_FALSE(absl::CUnescape(e, &out)); } } -- cgit v1.2.3 From 9ee91d3e430fb33a4590486573792eb0fa146c2d Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 8 Aug 2019 10:56:58 -0700 Subject: Export of internal Abseil changes -- f51743aa96e19aa3dda96d09d313b4390f1d61e7 by CJ Johnson : Minor touchup on the InlinedVector/Storage internal header file PiperOrigin-RevId: 262389640 -- e2f54c1f7142e40d30ff0fda43bef050625821a5 by Abseil Team : Update the absl codebase to use proper marketing names for macOS and Xcode PiperOrigin-RevId: 262389450 -- f29aae774edd0d00e2daa1fb96694a6dc3565a55 by CJ Johnson : Blocks code generator script from being affected by LTS inline namespaces PiperOrigin-RevId: 262376791 GitOrigin-RevId: f51743aa96e19aa3dda96d09d313b4390f1d61e7 Change-Id: I33be7f5a708ce8a2b7111b00151e43d73c5e0009 --- README.md | 2 +- absl/base/config.h | 4 +- absl/base/internal/endian.h | 2 +- absl/container/internal/inlined_vector.h | 158 ++++++++++++--------- absl/debugging/internal/stacktrace_powerpc-inl.inc | 2 +- .../internal/gaussian_distribution_gentables.cc | 14 +- absl/random/internal/platform.h | 2 +- absl/strings/numbers_test.cc | 2 +- absl/time/format_test.cc | 2 +- ci/macos_xcode_bazel.sh | 2 +- ci/macos_xcode_cmake.sh | 2 +- 11 files changed, 108 insertions(+), 84 deletions(-) mode change 100644 => 100755 ci/macos_xcode_bazel.sh mode change 100644 => 100755 ci/macos_xcode_cmake.sh (limited to 'absl/base/config.h') diff --git a/README.md b/README.md index 2c513ea6..85de5696 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ the Abseil code, running tests, and getting a simple binary working. ## Building Abseil [Bazel](https://bazel.build) is the official build system for Abseil, -which is supported on most major platforms (Linux, Windows, MacOS, for example) +which is supported on most major platforms (Linux, Windows, macOS, for example) and compilers. See the [quickstart](https://abseil.io/docs/cpp/quickstart) for more information on building Abseil using the Bazel build system. diff --git a/absl/base/config.h b/absl/base/config.h index 181d840e..1c3cb08e 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -260,7 +260,7 @@ // Linux and Linux-derived __linux__ // Android __ANDROID__ (implies __linux__) // Linux (non-Android) __linux__ && !__ANDROID__ -// Darwin (Mac OS X and iOS) __APPLE__ +// Darwin (macOS and iOS) __APPLE__ // Akaros (http://akaros.org) __ros__ // Windows _WIN32 // NaCL __native_client__ @@ -370,7 +370,7 @@ #error "absl endian detection needs to be set up for your compiler" #endif -// MacOS 10.13 and iOS 10.11 don't let you use , , or +// macOS 10.13 and iOS 10.11 don't let you use , , or // even though the headers exist and are publicly noted to work. See // https://github.com/abseil/abseil-cpp/issues/207 and // https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes diff --git a/absl/base/internal/endian.h b/absl/base/internal/endian.h index 6b828b6e..296e92d9 100644 --- a/absl/base/internal/endian.h +++ b/absl/base/internal/endian.h @@ -20,7 +20,7 @@ #ifdef _MSC_VER #include // NOLINT(build/include) #elif defined(__APPLE__) -// Mac OS X / Darwin features +// macOS / Darwin features #include #elif defined(__FreeBSD__) #include diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h index 17e203e5..61c4f6eb 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -270,6 +271,19 @@ class Storage { using ConstructionTransaction = inlined_vector_internal::ConstructionTransaction; + static size_type NextCapacity(size_type current_capacity) { + return current_capacity * 2; + } + + static size_type ComputeCapacity(size_type current_capacity, + size_type requested_capacity) { + return (std::max)(NextCapacity(current_capacity), requested_capacity); + } + + // --------------------------------------------------------------------------- + // Storage Constructors and Destructor + // --------------------------------------------------------------------------- + Storage() : metadata_() {} explicit Storage(const allocator_type& alloc) @@ -281,10 +295,26 @@ class Storage { DeallocateIfAllocated(); } + // --------------------------------------------------------------------------- + // Storage Member Accessors + // --------------------------------------------------------------------------- + + size_type& GetSizeAndIsAllocated() { return metadata_.template get<1>(); } + + const size_type& GetSizeAndIsAllocated() const { + return metadata_.template get<1>(); + } + size_type GetSize() const { return GetSizeAndIsAllocated() >> 1; } bool GetIsAllocated() const { return GetSizeAndIsAllocated() & 1; } + pointer GetAllocatedData() { return data_.allocated.allocated_data; } + + const_pointer GetAllocatedData() const { + return data_.allocated.allocated_data; + } + pointer GetInlinedData() { return reinterpret_cast( std::addressof(data_.inlined.inlined_data[0])); @@ -295,18 +325,12 @@ class Storage { std::addressof(data_.inlined.inlined_data[0])); } - pointer GetAllocatedData() { return data_.allocated.allocated_data; } - - const_pointer GetAllocatedData() const { - return data_.allocated.allocated_data; - } - - size_type GetInlinedCapacity() const { return static_cast(N); } - size_type GetAllocatedCapacity() const { return data_.allocated.allocated_capacity; } + size_type GetInlinedCapacity() const { return static_cast(N); } + StorageView MakeStorageView() { return GetIsAllocated() ? StorageView{GetAllocatedData(), GetSize(), @@ -322,30 +346,63 @@ class Storage { return std::addressof(metadata_.template get<0>()); } - void SetIsAllocated() { GetSizeAndIsAllocated() |= 1; } + // --------------------------------------------------------------------------- + // Storage Member Mutators + // --------------------------------------------------------------------------- - void UnsetIsAllocated() { - SetIsAllocated(); - GetSizeAndIsAllocated() -= 1; - } + template + void Initialize(ValueAdapter values, size_type new_size); - void SetAllocatedSize(size_type size) { - GetSizeAndIsAllocated() = (size << 1) | static_cast(1); + template + void Assign(ValueAdapter values, size_type new_size); + + template + void Resize(ValueAdapter values, size_type new_size); + + template + iterator Insert(const_iterator pos, ValueAdapter values, + size_type insert_count); + + template + reference EmplaceBack(Args&&... args); + + iterator Erase(const_iterator from, const_iterator to); + + void Reserve(size_type requested_capacity); + + void ShrinkToFit(); + + void Swap(Storage* other_storage_ptr); + + void SetIsAllocated() { + GetSizeAndIsAllocated() |= static_cast(1); } - void SetInlinedSize(size_type size) { GetSizeAndIsAllocated() = size << 1; } + void UnsetIsAllocated() { + GetSizeAndIsAllocated() &= ((std::numeric_limits::max)() - 1); + } void SetSize(size_type size) { GetSizeAndIsAllocated() = (size << 1) | static_cast(GetIsAllocated()); } - void AddSize(size_type count) { GetSizeAndIsAllocated() += count << 1; } + void SetAllocatedSize(size_type size) { + GetSizeAndIsAllocated() = (size << 1) | static_cast(1); + } + + void SetInlinedSize(size_type size) { + GetSizeAndIsAllocated() = size << static_cast(1); + } + + void AddSize(size_type count) { + GetSizeAndIsAllocated() += count << static_cast(1); + } void SubtractSize(size_type count) { assert(count <= GetSize()); - GetSizeAndIsAllocated() -= count << 1; + GetSizeAndIsAllocated() -= count << static_cast(1); } void SetAllocatedData(pointer data, size_type capacity) { @@ -353,14 +410,7 @@ class Storage { data_.allocated.allocated_capacity = capacity; } - void DeallocateIfAllocated() { - if (GetIsAllocated()) { - AllocatorTraits::deallocate(*GetAllocPtr(), GetAllocatedData(), - GetAllocatedCapacity()); - } - } - - void AcquireAllocation(AllocationTransaction* allocation_tx_ptr) { + void AcquireAllocatedData(AllocationTransaction* allocation_tx_ptr) { SetAllocatedData(allocation_tx_ptr->GetData(), allocation_tx_ptr->GetCapacity()); allocation_tx_ptr->GetData() = nullptr; @@ -374,46 +424,14 @@ class Storage { data_ = other_storage.data_; } - template - void Initialize(ValueAdapter values, size_type new_size); - - template - void Assign(ValueAdapter values, size_type new_size); - - template - void Resize(ValueAdapter values, size_type new_size); - - template - iterator Insert(const_iterator pos, ValueAdapter values, - size_type insert_count); - - template - reference EmplaceBack(Args&&... args); - - iterator Erase(const_iterator from, const_iterator to); - - void Reserve(size_type requested_capacity); - - void ShrinkToFit(); - - void Swap(Storage* other_storage_ptr); - - private: - size_type& GetSizeAndIsAllocated() { return metadata_.template get<1>(); } - - const size_type& GetSizeAndIsAllocated() const { - return metadata_.template get<1>(); - } - - static size_type NextCapacity(size_type current_capacity) { - return current_capacity * 2; - } - - static size_type ComputeCapacity(size_type current_capacity, - size_type requested_capacity) { - return (std::max)(NextCapacity(current_capacity), requested_capacity); + void DeallocateIfAllocated() { + if (GetIsAllocated()) { + AllocatorTraits::deallocate(*GetAllocPtr(), GetAllocatedData(), + GetAllocatedCapacity()); + } } + private: using Metadata = container_internal::CompressedTuple; @@ -508,7 +526,7 @@ auto Storage::Assign(ValueAdapter values, size_type new_size) -> void { if (allocation_tx.DidAllocate()) { DeallocateIfAllocated(); - AcquireAllocation(&allocation_tx); + AcquireAllocatedData(&allocation_tx); SetIsAllocated(); } @@ -557,7 +575,7 @@ auto Storage::Resize(ValueAdapter values, size_type new_size) -> void { construction_tx.Commit(); if (allocation_tx.DidAllocate()) { DeallocateIfAllocated(); - AcquireAllocation(&allocation_tx); + AcquireAllocatedData(&allocation_tx); SetIsAllocated(); } @@ -600,7 +618,7 @@ auto Storage::Insert(const_iterator pos, ValueAdapter values, construction_tx.Commit(); move_construciton_tx.Commit(); DeallocateIfAllocated(); - AcquireAllocation(&allocation_tx); + AcquireAllocatedData(&allocation_tx); SetAllocatedSize(new_size); return iterator(new_data + insert_index); @@ -697,7 +715,7 @@ auto Storage::EmplaceBack(Args&&... args) -> reference { storage_view.size); DeallocateIfAllocated(); - AcquireAllocation(&allocation_tx); + AcquireAllocatedData(&allocation_tx); SetIsAllocated(); } @@ -754,7 +772,7 @@ auto Storage::Reserve(size_type requested_capacity) -> void { storage_view.size); DeallocateIfAllocated(); - AcquireAllocation(&allocation_tx); + AcquireAllocatedData(&allocation_tx); SetIsAllocated(); } @@ -800,7 +818,7 @@ auto Storage::ShrinkToFit() -> void { storage_view.capacity); if (allocation_tx.DidAllocate()) { - AcquireAllocation(&allocation_tx); + AcquireAllocatedData(&allocation_tx); } else { UnsetIsAllocated(); } diff --git a/absl/debugging/internal/stacktrace_powerpc-inl.inc b/absl/debugging/internal/stacktrace_powerpc-inl.inc index 9e0f2aad..3a070ee4 100644 --- a/absl/debugging/internal/stacktrace_powerpc-inl.inc +++ b/absl/debugging/internal/stacktrace_powerpc-inl.inc @@ -162,7 +162,7 @@ ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY // May read random elements from stack. static int UnwindImpl(void** result, int* sizes, int max_depth, int skip_count, const void *ucp, int *min_dropped_frames) { void **sp; - // Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther) + // Apple macOS uses an old version of gnu as -- both Darwin 7.9.0 (Panther) // and Darwin 8.8.1 (Tiger) use as 1.38. This means we have to use a // different asm syntax. I don't know quite the best way to discriminate // systems using the old as from the new one; I've gone with __APPLE__. diff --git a/absl/random/internal/gaussian_distribution_gentables.cc b/absl/random/internal/gaussian_distribution_gentables.cc index 85247966..16a23cb2 100644 --- a/absl/random/internal/gaussian_distribution_gentables.cc +++ b/absl/random/internal/gaussian_distribution_gentables.cc @@ -110,8 +110,12 @@ void TableGenerator::Print(std::ostream* os) { "\n" "#include \"absl/random/gaussian_distribution.h\"\n" "\n" - "namespace absl {\n" - "namespace random_internal {\n" + // "namespace " and "absl" are broken apart so as not to conflict with + // script that adds the LTS inline namespace. + "namespace " + "absl {\n" + "namespace " + "random_internal {\n" "\n" "const gaussian_distribution_base::Tables\n" " gaussian_distribution_base::zg_ = {\n"; @@ -120,8 +124,10 @@ void TableGenerator::Print(std::ostream* os) { FormatArrayContents(os, tables_.f); *os << "};\n" "\n" - "} // namespace random_internal\n" - "} // namespace absl\n" + "} // namespace " + "random_internal\n" + "} // namespace " + "absl\n" "\n" "// clang-format on\n" "// END GENERATED CODE"; diff --git a/absl/random/internal/platform.h b/absl/random/internal/platform.h index d1ef5c24..a5a42cbb 100644 --- a/absl/random/internal/platform.h +++ b/absl/random/internal/platform.h @@ -30,7 +30,7 @@ // Linux and Linux-derived __linux__ // Android __ANDROID__ (implies __linux__) // Linux (non-Android) __linux__ && !__ANDROID__ -// Darwin (Mac OS X and iOS) __APPLE__ +// Darwin (macOS and iOS) __APPLE__ // Akaros (http://akaros.org) __ros__ // Windows _WIN32 // NaCL __native_client__ diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index ca2ee485..77d7e783 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -713,7 +713,7 @@ TEST(stringtest, safe_strtou64_base_length_delimited) { } } -// feenableexcept() and fedisableexcept() are missing on Mac OS X, MSVC, +// feenableexcept() and fedisableexcept() are missing on macOS, MSVC, // and WebAssembly. #if defined(_MSC_VER) || defined(__APPLE__) || defined(__EMSCRIPTEN__) #define ABSL_MISSING_FEENABLEEXCEPT 1 diff --git a/absl/time/format_test.cc b/absl/time/format_test.cc index 4a1f1aa2..ab1f3059 100644 --- a/absl/time/format_test.cc +++ b/absl/time/format_test.cc @@ -201,7 +201,7 @@ TEST(ParseTime, ErrorCases) { err.clear(); EXPECT_FALSE(absl::ParseTime("%Q", "x", &t, &err)) << err; // Exact contents of "err" are platform-dependent because of - // differences in the strptime implementation between OSX and Linux. + // differences in the strptime implementation between macOS and Linux. EXPECT_FALSE(err.empty()); // Fails because of trailing, unparsed data "blah". diff --git a/ci/macos_xcode_bazel.sh b/ci/macos_xcode_bazel.sh old mode 100644 new mode 100755 index e840e9d0..f0f14280 --- a/ci/macos_xcode_bazel.sh +++ b/ci/macos_xcode_bazel.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This script is invoked on Kokoro to test Abseil on MacOS. +# This script is invoked on Kokoro to test Abseil on macOS. # It is not hermetic and may break when Kokoro is updated. set -euox pipefail diff --git a/ci/macos_xcode_cmake.sh b/ci/macos_xcode_cmake.sh old mode 100644 new mode 100755 index 4892e26e..75b0f2d1 --- a/ci/macos_xcode_cmake.sh +++ b/ci/macos_xcode_cmake.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This script is invoked on Kokoro to test Abseil on MacOS. +# This script is invoked on Kokoro to test Abseil on macOS. # It is not hermetic and may break when Kokoro is updated. set -euox pipefail -- cgit v1.2.3 From aae8143cf9aa611f70d7ea9b95b8b8b383b2271a Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 15 Aug 2019 10:06:39 -0700 Subject: Export of internal Abseil changes -- f28b989d5161230c6561e923b458c797a96bcf90 by Greg Falcon : Import of CCTZ from GitHub. PiperOrigin-RevId: 263586488 -- 8259484025b7de45358719fc6182a48cac8044c6 by Andy Soffer : Internal changes and combine namespaces into a single namespace. PiperOrigin-RevId: 263560576 -- 8d19f41661984a600d1f8bbfeb8a30fcb4dee7d6 by Mark Barolak : Inside of absl::string_view::copy, use absl::string_view::traits_type::copy instead of std:copy to do the actual work. This both follows the C++ standard more closely and avoids avoid MSVC unchecked iterator warnings. PiperOrigin-RevId: 263430502 -- c06bf74236e12c7c1c97bfcbbc9d29bd65d6b36c by Andy Soffer : Remove force-inlining attributes. Benchmarking results indicate that they are creating meaningful performance differences. PiperOrigin-RevId: 263364896 -- ec4fa6eac958a9521456201b138784f55d3b17bc by Abseil Team : Make BM_Fill benchmarks more representative. PiperOrigin-RevId: 263349482 -- 4ae280b4eb31d9cb58e847eb670473340f7778c1 by Derek Mauro : Fix new -Wdeprecated-copy warning in gcc9 PiperOrigin-RevId: 263348118 -- d238a92f452a5c35686f9c71596fdd1fe62090a2 by Matt Calabrese : The std::is_trivially_xxx fail on versions of GCC up until 7.4 due to faulty underlying intrinsics, but our emulation succeeds. Update our traits to not compare against the standard library implementation in these versions. PiperOrigin-RevId: 263209457 GitOrigin-RevId: f28b989d5161230c6561e923b458c797a96bcf90 Change-Id: I4c41db5928ba71e243aeace4420e06d1a2df0b5b --- absl/base/config.h | 2 +- absl/container/btree_test.cc | 2 + absl/container/inlined_vector_benchmark.cc | 37 ++++---- absl/meta/type_traits_test.cc | 22 +++++ absl/random/internal/BUILD.bazel | 5 +- absl/random/internal/randen_hwaes.cc | 128 ++++++++------------------ absl/random/internal/uniform_helper.h | 3 - absl/strings/string_view.h | 2 +- absl/time/internal/cctz/src/time_zone_impl.cc | 13 ++- 9 files changed, 98 insertions(+), 116 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index 1c3cb08e..90d98214 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -125,7 +125,7 @@ #error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set #elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ (!defined(__clang__) && defined(__GNUC__) && \ - (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)) && \ + (__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ >= 4)) && \ (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \ (defined(_MSC_VER) && !defined(__NVCC__)) #define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc index a330cca3..3ac97f89 100644 --- a/absl/container/btree_test.cc +++ b/absl/container/btree_test.cc @@ -323,6 +323,7 @@ class unique_checker : public base_checker { unique_checker(const unique_checker &x) : super_type(x) {} template unique_checker(InputIterator b, InputIterator e) : super_type(b, e) {} + unique_checker& operator=(const unique_checker&) = default; // Insertion routines. std::pair insert(const value_type &x) { @@ -370,6 +371,7 @@ class multi_checker : public base_checker { multi_checker(const multi_checker &x) : super_type(x) {} template multi_checker(InputIterator b, InputIterator e) : super_type(b, e) {} + multi_checker& operator=(const multi_checker&) = default; // Insertion routines. iterator insert(const value_type &x) { diff --git a/absl/container/inlined_vector_benchmark.cc b/absl/container/inlined_vector_benchmark.cc index b99bbd62..3f2b4ed2 100644 --- a/absl/container/inlined_vector_benchmark.cc +++ b/absl/container/inlined_vector_benchmark.cc @@ -25,42 +25,45 @@ namespace { void BM_InlinedVectorFill(benchmark::State& state) { + const int len = state.range(0); absl::InlinedVector v; - int val = 10; + v.reserve(len); for (auto _ : state) { + v.resize(0); // Use resize(0) as InlinedVector releases storage on clear(). + for (int i = 0; i < len; ++i) { + v.push_back(i); + } benchmark::DoNotOptimize(v); - v.push_back(val); } } -BENCHMARK(BM_InlinedVectorFill)->Range(0, 1024); +BENCHMARK(BM_InlinedVectorFill)->Range(1, 256); void BM_InlinedVectorFillRange(benchmark::State& state) { const int len = state.range(0); - std::unique_ptr ia(new int[len]); - for (int i = 0; i < len; i++) { - ia[i] = i; - } - auto* from = ia.get(); - auto* to = from + len; + const std::vector src(len, len); + absl::InlinedVector v; + v.reserve(len); for (auto _ : state) { - benchmark::DoNotOptimize(from); - benchmark::DoNotOptimize(to); - absl::InlinedVector v(from, to); + benchmark::DoNotOptimize(src); + v.assign(src.begin(), src.end()); benchmark::DoNotOptimize(v); } } -BENCHMARK(BM_InlinedVectorFillRange)->Range(0, 1024); +BENCHMARK(BM_InlinedVectorFillRange)->Range(1, 256); void BM_StdVectorFill(benchmark::State& state) { + const int len = state.range(0); std::vector v; - int val = 10; + v.reserve(len); for (auto _ : state) { + v.clear(); + for (int i = 0; i < len; ++i) { + v.push_back(i); + } benchmark::DoNotOptimize(v); - benchmark::DoNotOptimize(val); - v.push_back(val); } } -BENCHMARK(BM_StdVectorFill)->Range(0, 1024); +BENCHMARK(BM_StdVectorFill)->Range(1, 256); // The purpose of the next two benchmarks is to verify that // absl::InlinedVector is efficient when moving is more efficent than diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc index a7a9c5c9..6fbb42f8 100644 --- a/absl/meta/type_traits_test.cc +++ b/absl/meta/type_traits_test.cc @@ -546,6 +546,28 @@ TEST(TypeTraitsTest, TestTrivialDefaultCtor) { #endif } +// GCC prior to 7.4 had a bug in its trivially-constructible traits +// (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80654). +// This test makes sure that we do not depend on the trait in these cases when +// implementing absl triviality traits. + +template +struct BadConstructors { + BadConstructors() { static_assert(T::value, ""); } + + BadConstructors(BadConstructors&&) { static_assert(T::value, ""); } + + BadConstructors(const BadConstructors&) { static_assert(T::value, ""); } +}; + +TEST(TypeTraitsTest, TestTrivialityBadConstructors) { + using BadType = BadConstructors; + + EXPECT_FALSE(absl::is_trivially_default_constructible::value); + EXPECT_FALSE(absl::is_trivially_move_constructible::value); + EXPECT_FALSE(absl::is_trivially_copy_constructible::value); +} + TEST(TypeTraitsTest, TestTrivialMoveCtor) { // Verify that arithmetic types and pointers have trivial move // constructors. diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index 7416e936..d9581d00 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -306,7 +306,10 @@ cc_library( # anyway and thus there wouldn't be any gain from using it as a module. features = ["-header_modules"], linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [":platform"], + deps = [ + ":platform", + "//absl/base:core_headers", + ], ) cc_binary( diff --git a/absl/random/internal/randen_hwaes.cc b/absl/random/internal/randen_hwaes.cc index 6b82d1d0..7d5b2b74 100644 --- a/absl/random/internal/randen_hwaes.cc +++ b/absl/random/internal/randen_hwaes.cc @@ -22,39 +22,9 @@ #include #include +#include "absl/base/attributes.h" #include "absl/random/internal/platform.h" -// ABSL_HAVE_ATTRIBUTE -#if !defined(ABSL_HAVE_ATTRIBUTE) -#ifdef __has_attribute -#define ABSL_HAVE_ATTRIBUTE(x) __has_attribute(x) -#else -#define ABSL_HAVE_ATTRIBUTE(x) 0 -#endif -#endif - -#if ABSL_HAVE_ATTRIBUTE(always_inline) || \ - (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE \ - __attribute__((always_inline)) -#elif defined(_MSC_VER) -// We can achieve something similar to attribute((always_inline)) with MSVC by -// using the __forceinline keyword, however this is not perfect. MSVC is -// much less aggressive about inlining, and even with the __forceinline keyword. -#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE __forceinline -#else -#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE -#endif - -// ABSL_ATTRIBUTE_FLATTEN enables much more aggressive inlining within -// the indicated function. -#undef ABSL_ATTRIBUTE_FLATTEN -#if ABSL_HAVE_ATTRIBUTE(flatten) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_ATTRIBUTE_FLATTEN __attribute__((flatten)) -#else -#define ABSL_ATTRIBUTE_FLATTEN -#endif - // ABSL_RANDEN_HWAES_IMPL indicates whether this file will contain // a hardware accelerated implementation of randen, or whether it // will contain stubs that exit the process. @@ -146,18 +116,6 @@ void RandenHwAes::Generate(const void*, void*) { #include "absl/random/internal/randen_traits.h" -// ABSL_FUNCTION_ALIGN32 defines a 32-byte alignment attribute -// for the functions in this file. -// -// NOTE: Determine whether we actually have any wins from ALIGN32 -// using microbenchmarks. If not, remove. -#undef ABSL_FUNCTION_ALIGN32 -#if ABSL_HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_FUNCTION_ALIGN32 __attribute__((aligned(32))) -#else -#define ABSL_FUNCTION_ALIGN32 -#endif - // TARGET_CRYPTO defines a crypto attribute for each architecture. // // NOTE: Evaluate whether we should eliminate ABSL_TARGET_CRYPTO. @@ -191,8 +149,7 @@ using Vector128 = __vector unsigned long long; // NOLINT(runtime/int) namespace { -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 -ReverseBytes(const Vector128& v) { +inline ABSL_TARGET_CRYPTO Vector128 ReverseBytes(const Vector128& v) { // Reverses the bytes of the vector. const __vector unsigned char perm = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; @@ -202,26 +159,26 @@ ReverseBytes(const Vector128& v) { // WARNING: these load/store in native byte order. It is OK to load and then // store an unchanged vector, but interpreting the bits as a number or input // to AES will have undefined results. -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 +inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* ABSL_RANDOM_INTERNAL_RESTRICT from) { return vec_vsx_ld(0, reinterpret_cast(from)); } -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void -Vector128Store(const Vector128& v, void* ABSL_RANDOM_INTERNAL_RESTRICT to) { +inline ABSL_TARGET_CRYPTO void Vector128Store( + const Vector128& v, void* ABSL_RANDOM_INTERNAL_RESTRICT to) { vec_vsx_st(v, 0, reinterpret_cast(to)); } // One round of AES. "round_key" is a public constant for breaking the // symmetry of AES (ensures previously equal columns differ afterwards). -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 -AesRound(const Vector128& state, const Vector128& round_key) { +inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, + const Vector128& round_key) { return Vector128(__builtin_crypto_vcipher(state, round_key)); } // Enables native loads in the round loop by pre-swapping. -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void -SwapEndian(uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) { +inline ABSL_TARGET_CRYPTO void SwapEndian( + uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) { using absl::random_internal::RandenTraits; constexpr size_t kLanes = 2; constexpr size_t kFeistelBlocks = RandenTraits::kFeistelBlocks; @@ -273,20 +230,20 @@ using Vector128 = uint8x16_t; namespace { -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 +inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* ABSL_RANDOM_INTERNAL_RESTRICT from) { return vld1q_u8(reinterpret_cast(from)); } -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void -Vector128Store(const Vector128& v, void* ABSL_RANDOM_INTERNAL_RESTRICT to) { +inline ABSL_TARGET_CRYPTO void Vector128Store( + const Vector128& v, void* ABSL_RANDOM_INTERNAL_RESTRICT to) { vst1q_u8(reinterpret_cast(to), v); } // One round of AES. "round_key" is a public constant for breaking the // symmetry of AES (ensures previously equal columns differ afterwards). -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 -AesRound(const Vector128& state, const Vector128& round_key) { +inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, + const Vector128& round_key) { // It is important to always use the full round function - omitting the // final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf] // and does not help because we never decrypt. @@ -297,8 +254,8 @@ AesRound(const Vector128& state, const Vector128& round_key) { return vaesmcq_u8(vaeseq_u8(state, uint8x16_t{})) ^ round_key; } -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void -SwapEndian(uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT) {} +inline ABSL_TARGET_CRYPTO void SwapEndian( + uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT) {} } // namespace @@ -313,16 +270,11 @@ namespace { class Vector128 { public: // Convert from/to intrinsics. - inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE explicit Vector128( - const __m128i& Vector128) - : data_(Vector128) {} + inline explicit Vector128(const __m128i& Vector128) : data_(Vector128) {} - inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE __m128i data() const { - return data_; - } + inline __m128i data() const { return data_; } - inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128& operator^=( - const Vector128& other) { + inline Vector128& operator^=(const Vector128& other) { data_ = _mm_xor_si128(data_, other.data()); return *this; } @@ -331,29 +283,29 @@ class Vector128 { __m128i data_; }; -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 +inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* ABSL_RANDOM_INTERNAL_RESTRICT from) { return Vector128(_mm_load_si128(reinterpret_cast(from))); } -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void -Vector128Store(const Vector128& v, void* ABSL_RANDOM_INTERNAL_RESTRICT to) { +inline ABSL_TARGET_CRYPTO void Vector128Store( + const Vector128& v, void* ABSL_RANDOM_INTERNAL_RESTRICT to) { _mm_store_si128(reinterpret_cast<__m128i * ABSL_RANDOM_INTERNAL_RESTRICT>(to), v.data()); } // One round of AES. "round_key" is a public constant for breaking the // symmetry of AES (ensures previously equal columns differ afterwards). -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128 -AesRound(const Vector128& state, const Vector128& round_key) { +inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state, + const Vector128& round_key) { // It is important to always use the full round function - omitting the // final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf] // and does not help because we never decrypt. return Vector128(_mm_aesenc_si128(state.data(), round_key.data())); } -inline ABSL_TARGET_CRYPTO ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void -SwapEndian(uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT) {} +inline ABSL_TARGET_CRYPTO void SwapEndian( + uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT) {} } // namespace @@ -450,8 +402,8 @@ constexpr size_t kLanes = 2; // Block shuffles applies a shuffle to the entire state between AES rounds. // Improved odd-even shuffle from "New criterion for diffusion property". -inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE ABSL_TARGET_CRYPTO void -BlockShuffle(uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) { +inline ABSL_TARGET_CRYPTO void BlockShuffle( + uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) { static_assert(kFeistelBlocks == 16, "Expecting 16 FeistelBlocks."); constexpr size_t shuffle[kFeistelBlocks] = {7, 2, 13, 4, 11, 8, 3, 6, @@ -499,10 +451,9 @@ BlockShuffle(uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) { // per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in // parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel // XORs are 'free' (included in the second AES instruction). -inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE ABSL_TARGET_CRYPTO const - u64x2* - FeistelRound(uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state, - const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { +inline ABSL_TARGET_CRYPTO const u64x2* FeistelRound( + uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state, + const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys) { static_assert(kFeistelBlocks == 16, "Expecting 16 FeistelBlocks."); // MSVC does a horrible job at unrolling loops. @@ -561,9 +512,9 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE ABSL_TARGET_CRYPTO const // Indistinguishable from ideal by chosen-ciphertext adversaries using less than // 2^64 queries if the round function is a PRF. This is similar to the b=8 case // of Simpira v2, but more efficient than its generic construction for b=16. -inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE ABSL_TARGET_CRYPTO void -Permute(const void* ABSL_RANDOM_INTERNAL_RESTRICT keys, - uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) { +inline ABSL_TARGET_CRYPTO void Permute( + const void* ABSL_RANDOM_INTERNAL_RESTRICT keys, + uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state) { const u64x2* ABSL_RANDOM_INTERNAL_RESTRICT keys128 = static_cast(keys); @@ -584,16 +535,15 @@ namespace random_internal { bool HasRandenHwAesImplementation() { return true; } -const void* ABSL_TARGET_CRYPTO ABSL_FUNCTION_ALIGN32 ABSL_ATTRIBUTE_FLATTEN -RandenHwAes::GetKeys() { +const void* ABSL_TARGET_CRYPTO RandenHwAes::GetKeys() { // Round keys for one AES per Feistel round and branch. // The canonical implementation uses first digits of Pi. return round_keys; } // NOLINTNEXTLINE -void ABSL_TARGET_CRYPTO ABSL_FUNCTION_ALIGN32 ABSL_ATTRIBUTE_FLATTEN -RandenHwAes::Absorb(const void* seed_void, void* state_void) { +void ABSL_TARGET_CRYPTO RandenHwAes::Absorb(const void* seed_void, + void* state_void) { uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state = reinterpret_cast(state_void); const uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT seed = @@ -669,8 +619,8 @@ RandenHwAes::Absorb(const void* seed_void, void* state_void) { } // NOLINTNEXTLINE -void ABSL_TARGET_CRYPTO ABSL_FUNCTION_ALIGN32 ABSL_ATTRIBUTE_FLATTEN -RandenHwAes::Generate(const void* keys, void* state_void) { +void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys, + void* state_void) { static_assert(kCapacityBytes == sizeof(Vector128), "Capacity mismatch"); uint64_t* ABSL_RANDOM_INTERNAL_RESTRICT state = diff --git a/absl/random/internal/uniform_helper.h b/absl/random/internal/uniform_helper.h index 21646489..ebcc3744 100644 --- a/absl/random/internal/uniform_helper.h +++ b/absl/random/internal/uniform_helper.h @@ -35,9 +35,6 @@ struct IntervalClosedClosedT {}; struct IntervalClosedOpenT {}; struct IntervalOpenClosedT {}; struct IntervalOpenOpenT {}; -} // namespace random_internal - -namespace random_internal { // The functions // uniform_lower_bound(tag, a, b) diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 25a4d1ed..a1b5a17b 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -342,7 +342,7 @@ class string_view { size_type rlen = (std::min)(length_ - pos, n); if (rlen > 0) { const char* start = ptr_ + pos; - std::copy(start, start + rlen, buf); + traits_type::copy(buf, start, rlen); } return rlen; } diff --git a/absl/time/internal/cctz/src/time_zone_impl.cc b/absl/time/internal/cctz/src/time_zone_impl.cc index 3cbc6746..a26151d3 100644 --- a/absl/time/internal/cctz/src/time_zone_impl.cc +++ b/absl/time/internal/cctz/src/time_zone_impl.cc @@ -33,7 +33,12 @@ using TimeZoneImplByName = TimeZoneImplByName* time_zone_map = nullptr; // Mutual exclusion for time_zone_map. -std::mutex time_zone_mutex; +std::mutex& TimeZoneMutex() { + // This mutex is intentionally "leaked" to avoid the static deinitialization + // order fiasco (std::mutex's destructor is not trivial on many platforms). + static std::mutex* time_zone_mutex = new std::mutex; + return *time_zone_mutex; +} } // namespace @@ -54,7 +59,7 @@ bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { // Then check, under a shared lock, whether the time zone has already // been loaded. This is the common path. TODO: Move to shared_mutex. { - std::lock_guard lock(time_zone_mutex); + std::lock_guard lock(TimeZoneMutex()); if (time_zone_map != nullptr) { TimeZoneImplByName::const_iterator itr = time_zone_map->find(name); if (itr != time_zone_map->end()) { @@ -65,7 +70,7 @@ bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { } // Now check again, under an exclusive lock. - std::lock_guard lock(time_zone_mutex); + std::lock_guard lock(TimeZoneMutex()); if (time_zone_map == nullptr) time_zone_map = new TimeZoneImplByName; const Impl*& impl = (*time_zone_map)[name]; if (impl == nullptr) { @@ -84,7 +89,7 @@ bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { } void time_zone::Impl::ClearTimeZoneMapTestOnly() { - std::lock_guard lock(time_zone_mutex); + std::lock_guard lock(TimeZoneMutex()); if (time_zone_map != nullptr) { // Existing time_zone::Impl* entries are in the wild, so we simply // leak them. Future requests will result in reloading the data. -- cgit v1.2.3 From 97c1664b4bbab5f78fac2b151ab02656268fb34b Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 9 Sep 2019 08:20:10 -0700 Subject: Export of internal Abseil changes -- 167cd2647144583746311129b0cc98a89a9897e1 by Andy Soffer : Internal Changes PiperOrigin-RevId: 268000987 -- ab44fea7dfdaf763c69609a08ddfac22480ce520 by Derek Mauro : Fix flags Cmake tests on Windows PiperOrigin-RevId: 267859442 -- d7ec9f7611370b01bc9a5aed7e18460df2a15429 by Abseil Team : Fix undefined behavior in symbolize_elf.inc PiperOrigin-RevId: 267684904 -- e7c5f8e472a91ed99bdf4876942f2bda5751aa6c by Abseil Team : Turn off ABSL_HAS_ALARM on Fuchsia. PiperOrigin-RevId: 267666090 -- b7d25d5c71a49e697a8bf6440ed30f2e3f036420 by Chris Kennelly : Mark once initialization function as no inline. We expect this code to run infrequently. PiperOrigin-RevId: 267649713 -- dc2a5e5f1e39a03fff837d34a319033fde55d9ba by Derek Mauro : Fix the MSVC CMake random build PiperOrigin-RevId: 267624074 -- ba2751b67fa17d1b6c53e5ba79f81a5371e4a03a by Abseil Team : Move "internal/flag.*" files to the "internal" build target. PiperOrigin-RevId: 267588996 -- 05b985a33eec4f8acff1809ad9218a1e22220f34 by Abseil Team : Move "internal/flag.*" files to the "internal" build target. PiperOrigin-RevId: 267580412 GitOrigin-RevId: 167cd2647144583746311129b0cc98a89a9897e1 Change-Id: Ibd334f46a5671c7c1d3fcf5354029e2fbb7ba91f --- absl/base/call_once.h | 1 + absl/base/config.h | 2 + absl/debugging/symbolize_elf.inc | 13 +++- absl/flags/BUILD.bazel | 2 + absl/flags/CMakeLists.txt | 2 + absl/flags/flag_test.cc | 92 ++++++++++++++++++----------- absl/flags/internal/commandlineflag_test.cc | 34 +++++++++-- absl/flags/internal/usage_test.cc | 4 +- absl/random/CMakeLists.txt | 2 + absl/random/beta_distribution.h | 2 +- absl/random/distribution_format_traits.h | 39 ++++++++++++ absl/random/internal/BUILD.bazel | 9 +-- absl/random/internal/distributions.h | 12 ++-- absl/random/internal/uniform_helper.h | 2 +- 14 files changed, 154 insertions(+), 62 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/call_once.h b/absl/base/call_once.h index e7fc2300..4aa6360c 100644 --- a/absl/base/call_once.h +++ b/absl/base/call_once.h @@ -142,6 +142,7 @@ enum { }; template +ABSL_ATTRIBUTE_NOINLINE void CallOnceImpl(std::atomic* control, base_internal::SchedulingMode scheduling_mode, Callable&& fn, Args&&... args) { diff --git a/absl/base/config.h b/absl/base/config.h index 90d98214..1cb69b0f 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -336,6 +336,8 @@ // feature tests for Microsoft's library #elif defined(__EMSCRIPTEN__) // emscripten doesn't support signals +#elif defined(__Fuchsia__) +// Signals don't exist on fuchsia. #elif defined(__native_client__) #else // other standard libraries diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc index e7305213..14f0c972 100644 --- a/absl/debugging/symbolize_elf.inc +++ b/absl/debugging/symbolize_elf.inc @@ -624,6 +624,13 @@ static bool InSection(const void *address, const ElfW(Shdr) * section) { return start <= address && address < (start + size); } +static const char *ComputeOffset(const char *base, ptrdiff_t offset) { + // Note: cast to uintptr_t to avoid undefined behavior when base evaluates to + // zero and offset is non-zero. + return reinterpret_cast( + reinterpret_cast(base) + offset); +} + // Read a symbol table and look for the symbol containing the // pc. Iterate over symbols in a symbol table and look for the symbol // containing "pc". If the symbol is found, and its name fits in @@ -676,7 +683,8 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( // We keep the original address for opd redirection below. const char *const original_start_address = reinterpret_cast(symbol.st_value); - const char *start_address = original_start_address + relocation; + const char *start_address = + ComputeOffset(original_start_address, relocation); if (deref_function_descriptor_pointer && InSection(original_start_address, opd)) { @@ -688,8 +696,7 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( // If pc is inside the .opd section, it points to a function descriptor. const size_t size = pc_in_opd ? kFunctionDescriptorSize : symbol.st_size; - const void *const end_address = - reinterpret_cast(start_address) + size; + const void *const end_address = ComputeOffset(start_address, size); if (symbol.st_value != 0 && // Skip null value symbols. symbol.st_shndx != 0 && // Skip undefined symbols. #ifdef STT_TLS diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 4ed6585b..9e923ffb 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -231,6 +231,7 @@ cc_test( copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ + ":config", ":flag", ":handle", ":registry", @@ -264,6 +265,7 @@ cc_test( copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ + ":config", ":flag", "//absl/strings", "@com_google_googletest//:gtest_main", diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt index d9084a9c..3eac8f0a 100644 --- a/absl/flags/CMakeLists.txt +++ b/absl/flags/CMakeLists.txt @@ -213,6 +213,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::flags + absl::flags_config absl::flags_handle absl::flags_registry absl::memory @@ -242,6 +243,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::flags + absl::flags_config absl::strings gtest_main ) diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc index 1bcd7e96..a652042c 100644 --- a/absl/flags/flag_test.cc +++ b/absl/flags/flag_test.cc @@ -15,7 +15,11 @@ #include "absl/flags/flag.h" +#include +#include + #include "gtest/gtest.h" +#include "absl/flags/usage_config.h" #include "absl/strings/match.h" #include "absl/strings/numbers.h" #include "absl/strings/str_cat.h" @@ -63,7 +67,27 @@ struct UDT { bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; } std::string AbslUnparseFlag(const UDT&) { return ""; } -TEST(FlagTest, TestConstruction) { +class FlagTest : public testing::Test { + protected: + static void SetUpTestSuite() { + // Install a function to normalize filenames before this test is run. + absl::FlagsUsageConfig default_config; + default_config.normalize_filename = &FlagTest::NormalizeFileName; + absl::SetFlagsUsageConfig(default_config); + } + + private: + static std::string NormalizeFileName(absl::string_view fname) { +#ifdef _WIN32 + std::string normalized(fname); + std::replace(normalized.begin(), normalized.end(), '\\', '/'); + fname = normalized; +#endif + return std::string(fname); + } +}; + +TEST_F(FlagTest, TestConstruction) { TestConstructionFor(); TestConstructionFor(); TestConstructionFor(); @@ -98,7 +122,7 @@ namespace { #if !ABSL_FLAGS_STRIP_NAMES -TEST(FlagTest, TestFlagDeclaration) { +TEST_F(FlagTest, TestFlagDeclaration) { // test that we can access flag objects. EXPECT_EQ(FLAGS_test_flag_01.Name(), "test_flag_01"); EXPECT_EQ(FLAGS_test_flag_02.Name(), "test_flag_02"); @@ -133,69 +157,69 @@ ABSL_FLAG(std::string, test_flag_11, "", "test flag 11"); namespace { #if !ABSL_FLAGS_STRIP_NAMES -TEST(FlagTest, TestFlagDefinition) { +TEST_F(FlagTest, TestFlagDefinition) { absl::string_view expected_file_name = "absl/flags/flag_test.cc"; EXPECT_EQ(FLAGS_test_flag_01.Name(), "test_flag_01"); EXPECT_EQ(FLAGS_test_flag_01.Help(), "test flag 01"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_01.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_01.Filename(), expected_file_name)) + << FLAGS_test_flag_01.Filename(); EXPECT_EQ(FLAGS_test_flag_02.Name(), "test_flag_02"); EXPECT_EQ(FLAGS_test_flag_02.Help(), "test flag 02"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_02.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_02.Filename(), expected_file_name)) + << FLAGS_test_flag_02.Filename(); EXPECT_EQ(FLAGS_test_flag_03.Name(), "test_flag_03"); EXPECT_EQ(FLAGS_test_flag_03.Help(), "test flag 03"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_03.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_03.Filename(), expected_file_name)) + << FLAGS_test_flag_03.Filename(); EXPECT_EQ(FLAGS_test_flag_04.Name(), "test_flag_04"); EXPECT_EQ(FLAGS_test_flag_04.Help(), "test flag 04"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_04.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_04.Filename(), expected_file_name)) + << FLAGS_test_flag_04.Filename(); EXPECT_EQ(FLAGS_test_flag_05.Name(), "test_flag_05"); EXPECT_EQ(FLAGS_test_flag_05.Help(), "test flag 05"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_05.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_05.Filename(), expected_file_name)) + << FLAGS_test_flag_05.Filename(); EXPECT_EQ(FLAGS_test_flag_06.Name(), "test_flag_06"); EXPECT_EQ(FLAGS_test_flag_06.Help(), "test flag 06"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_06.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_06.Filename(), expected_file_name)) + << FLAGS_test_flag_06.Filename(); EXPECT_EQ(FLAGS_test_flag_07.Name(), "test_flag_07"); EXPECT_EQ(FLAGS_test_flag_07.Help(), "test flag 07"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_07.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_07.Filename(), expected_file_name)) + << FLAGS_test_flag_07.Filename(); EXPECT_EQ(FLAGS_test_flag_08.Name(), "test_flag_08"); EXPECT_EQ(FLAGS_test_flag_08.Help(), "test flag 08"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_08.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_08.Filename(), expected_file_name)) + << FLAGS_test_flag_08.Filename(); EXPECT_EQ(FLAGS_test_flag_09.Name(), "test_flag_09"); EXPECT_EQ(FLAGS_test_flag_09.Help(), "test flag 09"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_09.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_09.Filename(), expected_file_name)) + << FLAGS_test_flag_09.Filename(); EXPECT_EQ(FLAGS_test_flag_10.Name(), "test_flag_10"); EXPECT_EQ(FLAGS_test_flag_10.Help(), "test flag 10"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_10.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_10.Filename(), expected_file_name)) + << FLAGS_test_flag_10.Filename(); EXPECT_EQ(FLAGS_test_flag_11.Name(), "test_flag_11"); EXPECT_EQ(FLAGS_test_flag_11.Help(), "test flag 11"); - EXPECT_TRUE( - absl::EndsWith(FLAGS_test_flag_11.Filename(), expected_file_name)); + EXPECT_TRUE(absl::EndsWith(FLAGS_test_flag_11.Filename(), expected_file_name)) + << FLAGS_test_flag_11.Filename(); } #endif // !ABSL_FLAGS_STRIP_NAMES // -------------------------------------------------------------------- -TEST(FlagTest, TestDefault) { +TEST_F(FlagTest, TestDefault) { EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), true); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 1234); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), -34); @@ -211,7 +235,7 @@ TEST(FlagTest, TestDefault) { // -------------------------------------------------------------------- -TEST(FlagTest, TestGetSet) { +TEST_F(FlagTest, TestGetSet) { absl::SetFlag(&FLAGS_test_flag_01, false); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), false); @@ -258,7 +282,7 @@ ABSL_FLAG(std::string, test_flag_13, absl::StrCat("AAA", "BBB"), namespace { -TEST(FlagTest, TestNonConstexprDefault) { +TEST_F(FlagTest, TestNonConstexprDefault) { EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_12), 1); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_13), "AAABBB"); } @@ -272,7 +296,7 @@ ABSL_FLAG(bool, test_flag_14, true, absl::StrCat("test ", "flag ", "14")); namespace { #if !ABSL_FLAGS_STRIP_HELP -TEST(FlagTest, TestNonConstexprHelp) { +TEST_F(FlagTest, TestNonConstexprHelp) { EXPECT_EQ(FLAGS_test_flag_14.Help(), "test flag 14"); } #endif //! ABSL_FLAGS_STRIP_HELP @@ -296,7 +320,7 @@ namespace { void TestFlagCB() { cb_test_value = absl::GetFlag(FLAGS_test_flag_with_cb); } // Tests side-effects of callback invocation. -TEST(FlagTest, CallbackInvocation) { +TEST_F(FlagTest, CallbackInvocation) { EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_cb), 100); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_with_lambda_cb), 200); EXPECT_EQ(cb_test_value, 300); @@ -343,7 +367,7 @@ ABSL_FLAG(CustomUDT, test_flag_15, CustomUDT(), "test flag 15"); namespace { -TEST(FlagTest, TestCustomUDT) { +TEST_F(FlagTest, TestCustomUDT) { EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_15), CustomUDT(1, 1)); absl::SetFlag(&FLAGS_test_flag_15, CustomUDT(2, 3)); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_15), CustomUDT(2, 3)); @@ -409,7 +433,7 @@ ABSL_FLAG(ConversionTestVal, test_flag_16, namespace { -TEST(FlagTest, CanSetViaImplicitConversion) { +TEST_F(FlagTest, CanSetViaImplicitConversion) { EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_16).a, 10); absl::SetFlag(&FLAGS_test_flag_16, ConversionTestVal::ViaImplicitConv::kEleven); @@ -447,7 +471,7 @@ ABSL_FLAG(NonDfltConstructible, ndc_flag2, 0, namespace { -TEST(FlagTest, TestNonDefaultConstructibleType) { +TEST_F(FlagTest, TestNonDefaultConstructibleType) { EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag1).value, '1' + 100); EXPECT_EQ(absl::GetFlag(FLAGS_ndc_flag2).value, 0); @@ -468,7 +492,7 @@ ABSL_RETIRED_FLAG(std::string, old_str_flag, "", absl::StrCat("old ", "descr")); namespace { -TEST(FlagTest, TestRetiredFlagRegistration) { +TEST_F(FlagTest, TestRetiredFlagRegistration) { bool is_bool = false; EXPECT_TRUE(flags::IsRetiredFlag("old_bool_flag", &is_bool)); EXPECT_TRUE(is_bool); diff --git a/absl/flags/internal/commandlineflag_test.cc b/absl/flags/internal/commandlineflag_test.cc index f0d57adb..5a0c271e 100644 --- a/absl/flags/internal/commandlineflag_test.cc +++ b/absl/flags/internal/commandlineflag_test.cc @@ -15,9 +15,13 @@ #include "absl/flags/internal/commandlineflag.h" +#include +#include + #include "gtest/gtest.h" #include "absl/flags/flag.h" #include "absl/flags/internal/registry.h" +#include "absl/flags/usage_config.h" #include "absl/memory/memory.h" #include "absl/strings/match.h" #include "absl/strings/str_cat.h" @@ -33,10 +37,26 @@ namespace flags = absl::flags_internal; class CommandLineFlagTest : public testing::Test { protected: + static void SetUpTestSuite() { + // Install a function to normalize filenames before this test is run. + absl::FlagsUsageConfig default_config; + default_config.normalize_filename = &CommandLineFlagTest::NormalizeFileName; + absl::SetFlagsUsageConfig(default_config); + } + void SetUp() override { flag_saver_ = absl::make_unique(); } void TearDown() override { flag_saver_.reset(); } private: + static std::string NormalizeFileName(absl::string_view fname) { +#ifdef _WIN32 + std::string normalized(fname); + std::replace(normalized.begin(), normalized.end(), '\\', '/'); + fname = normalized; +#endif + return std::string(fname); + } + std::unique_ptr flag_saver_; }; @@ -49,9 +69,10 @@ TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) { EXPECT_EQ(flag_01->Typename(), ""); EXPECT_TRUE(!flag_01->IsRetired()); EXPECT_TRUE(flag_01->IsOfType()); - EXPECT_TRUE(absl::EndsWith( - flag_01->Filename(), - "absl/flags/internal/commandlineflag_test.cc")); + EXPECT_TRUE( + absl::EndsWith(flag_01->Filename(), + "absl/flags/internal/commandlineflag_test.cc")) + << flag_01->Filename(); auto* flag_02 = flags::FindCommandLineFlag("string_flag"); @@ -61,9 +82,10 @@ TEST_F(CommandLineFlagTest, TestAttributesAccessMethods) { EXPECT_EQ(flag_02->Typename(), ""); EXPECT_TRUE(!flag_02->IsRetired()); EXPECT_TRUE(flag_02->IsOfType()); - EXPECT_TRUE(absl::EndsWith( - flag_02->Filename(), - "absl/flags/internal/commandlineflag_test.cc")); + EXPECT_TRUE( + absl::EndsWith(flag_02->Filename(), + "absl/flags/internal/commandlineflag_test.cc")) + << flag_02->Filename(); auto* flag_03 = flags::FindRetiredFlag("bool_retired_flag"); diff --git a/absl/flags/internal/usage_test.cc b/absl/flags/internal/usage_test.cc index 8538b2b6..d15e4484 100644 --- a/absl/flags/internal/usage_test.cc +++ b/absl/flags/internal/usage_test.cc @@ -67,9 +67,9 @@ static std::string NormalizeFileName(absl::string_view fname) { fname = normalized; #endif - auto absl_pos = fname.find("/absl/"); + auto absl_pos = fname.rfind("absl/"); if (absl_pos != absl::string_view::npos) { - fname = fname.substr(absl_pos + 1); + fname = fname.substr(absl_pos); } return std::string(fname); } diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index cde89bfd..151cefa4 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -1025,6 +1025,8 @@ absl_cc_test( random_internal_iostream_state_saver_test SRCS "internal/iostream_state_saver_test.cc" + COPTS + ${ABSL_TEST_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS diff --git a/absl/random/beta_distribution.h b/absl/random/beta_distribution.h index d7afd61c..e29894f2 100644 --- a/absl/random/beta_distribution.h +++ b/absl/random/beta_distribution.h @@ -129,7 +129,7 @@ class beta_distribution { private: friend class beta_distribution; -#ifdef COMPILER_MSVC +#ifdef _MSC_VER // MSVC does not have constexpr implementations for std::log and std::exp // so they are computed at runtime. #define ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR diff --git a/absl/random/distribution_format_traits.h b/absl/random/distribution_format_traits.h index 3f28c906..3298c2cd 100644 --- a/absl/random/distribution_format_traits.h +++ b/absl/random/distribution_format_traits.h @@ -36,6 +36,12 @@ #include "absl/types/span.h" namespace absl { + +struct IntervalClosedClosedTag; +struct IntervalClosedOpenTag; +struct IntervalOpenClosedTag; +struct IntervalOpenOpenTag; + namespace random_internal { // ScalarTypeName defines a preferred hierarchy of preferred type names for @@ -243,6 +249,39 @@ struct DistributionFormatTraits> { } }; +template +struct UniformDistributionWrapper; + +template +struct DistributionFormatTraits> { + using distribution_t = UniformDistributionWrapper; + using result_t = NumType; + + static constexpr const char* Name() { return "Uniform"; } + + static std::string FunctionName() { + return absl::StrCat(Name(), "<", ScalarTypeName(), ">"); + } + static std::string FormatArgs(const distribution_t& d) { + absl::string_view tag; + if (std::is_same::value) { + tag = "IntervalClosedClosed"; + } else if (std::is_same::value) { + tag = "IntervalClosedOpen"; + } else if (std::is_same::value) { + tag = "IntervalOpenClosed"; + } else if (std::is_same::value) { + tag = "IntervalOpenOpen"; + } else { + tag = "[[unknown tag type]]"; + } + return absl::StrCat(tag, ", ", (d.min)(), ", ", (d.max)()); + } + static std::string FormatResults(absl::Span results) { + return absl::StrJoin(results, ", "); + } +}; + } // namespace random_internal } // namespace absl diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index 8eb6c61a..cd50982d 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -60,13 +60,11 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":distribution_caller", - ":fast_uniform_bits", - ":fastmath", ":traits", ":uniform_helper", + "//absl/base", "//absl/meta:type_traits", "//absl/strings", - "//absl/types:span", ], ) @@ -618,11 +616,6 @@ cc_library( copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ - ":distribution_impl", - ":fast_uniform_bits", - ":iostream_state_saver", - ":traits", - "//absl/base:core_headers", "//absl/meta:type_traits", ], ) diff --git a/absl/random/internal/distributions.h b/absl/random/internal/distributions.h index 34db3b32..96f8bae3 100644 --- a/absl/random/internal/distributions.h +++ b/absl/random/internal/distributions.h @@ -39,22 +39,20 @@ NumType UniformImpl(TagType tag, "absl::Uniform() must use an integer or real parameter type."); using distribution_t = - typename std::conditional::value, - absl::uniform_int_distribution, - absl::uniform_real_distribution>::type; + UniformDistributionWrapper, NumType>; using format_t = random_internal::DistributionFormatTraits; + auto a = uniform_lower_bound(tag, lo, hi); + auto b = uniform_upper_bound(tag, lo, hi); - auto a = random_internal::uniform_lower_bound(tag, lo, hi); - auto b = random_internal::uniform_upper_bound(tag, lo, hi); // TODO(lar): it doesn't make a lot of sense to ask for a random number in an // empty range. Right now we just return a boundary--even though that // boundary is not an acceptable value! Is there something better we can do // here? + if (a > b) return a; using gen_t = absl::decay_t; - if (a > b) return a; return DistributionCaller::template Call( - &urbg, a, b); + &urbg, tag, lo, hi); } // In the absence of an explicitly provided return-type, the template diff --git a/absl/random/internal/uniform_helper.h b/absl/random/internal/uniform_helper.h index 9e89e526..2929407e 100644 --- a/absl/random/internal/uniform_helper.h +++ b/absl/random/internal/uniform_helper.h @@ -156,7 +156,7 @@ using UniformDistribution = template struct UniformDistributionWrapper : public UniformDistribution { - explicit UniformDistributionWrapper(NumType lo, NumType hi) + explicit UniformDistributionWrapper(TagType, NumType lo, NumType hi) : UniformDistribution( uniform_lower_bound(TagType{}, lo, hi), uniform_upper_bound(TagType{}, lo, hi)) {} -- cgit v1.2.3 From abea769b551f7a100f540967cb95debdb0080df8 Mon Sep 17 00:00:00 2001 From: Joe Sylve Date: Wed, 9 Oct 2019 16:07:57 -0500 Subject: Fix ABSL_HAVE_ALARM check on mingw (#341) * Fix ABSL_HAVE_ALARM check on mingw --- absl/base/config.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index 1cb69b0f..039b73d8 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -334,6 +334,11 @@ #define ABSL_HAVE_ALARM 1 #elif defined(_MSC_VER) // feature tests for Microsoft's library +#elif defined(__MINGW32__) +// mingw32 doesn't provide alarm(2): +// https://osdn.net/projects/mingw/scm/git/mingw-org-wsl/blobs/5.2-trunk/mingwrt/include/unistd.h +// mingw-w64 provides a no-op implementation: +// https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-crt/misc/alarm.c #elif defined(__EMSCRIPTEN__) // emscripten doesn't support signals #elif defined(__Fuchsia__) -- cgit v1.2.3 From 078b89b3c046d230ef3ad39494e5852184eb528b Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 23 Oct 2019 19:35:39 -0700 Subject: Export of internal Abseil changes -- e54b9c7bbb0c58475676c268e2e19c69f4bce48a by Jorg Brown : Tweak ABSL_PREDICT_TRUE slightly, for better code on some platforms and/or optimization levels. "false || (x)" is more verbose than "!!(x)", but ultimately more efficient. For example, given this code: void InitIfNecessary() { if (ABSL_PREDICT_TRUE(NeedsInit())) { SlowInitIfNecessary(); } } Clang with default optimization level will produce: Before this CL After this CL InitIfNecessary: InitIfNecessary: push rbp push rbp mov rbp, rsp mov rbp, rsp call NeedsInit call NeedsInit xor al, -1 xor al, -1 test al, 1 test al, 1 jne .LBB2_1 jne .LBB3_1 jmp .LBB2_2 jmp .LBB3_2 .LBB2_1: .LBB3_1: call SlowInitIfNecessary call SlowInitIfNecessary .LBB2_2: .LBB3_2: pop rbp pop rbp ret ret PiperOrigin-RevId: 276401386 -- 0a3c4dfd8342bf2b1b11a87f1c662c883f73cab7 by Abseil Team : Fix comment nit: sem_open => sem_init. The code calls sem_init, not sem_open, to initialize an unnamed semaphore. (sem_open creates or opens a named semaphore.) PiperOrigin-RevId: 276344072 -- b36a664e9459057509a90e83d3482e1d3a4c44c7 by Abseil Team : Fix typo in flat_hash_map.h: exchaged -> exchanged PiperOrigin-RevId: 276295792 -- 7bbd8d18276eb110c8335743e35fceb662ddf3d6 by Samuel Benzaquen : Add assertions to verify use of iterators. PiperOrigin-RevId: 276283300 -- 677398a8ffcb1f59182cffe57a4fe7ff147a0404 by Laramie Leavitt : Migrate distribution_impl.h/cc to generate_real.h/cc. Combine the methods RandU64To into a single method: GenerateRealFromBits(). Remove rejection sampling from absl::uniform_real_distribution. PiperOrigin-RevId: 276158675 -- c60c9d11d24b0c546329d998e78e15a84b3153f5 by Abseil Team : Internal change PiperOrigin-RevId: 276126962 -- 4c840cab6a8d86efa29b397cafaf7520eece68cc by Andy Soffer : Update CMakeLists.txt to address https://github.com/abseil/abseil-cpp/issues/365. This does not cover every platform, but it does at least address the first-order issue of assuming gcc implies x86. PiperOrigin-RevId: 276116253 -- 98da366e6b5d51afe5d7ac6722126aca23d85ee6 by Abseil Team : Internal change PiperOrigin-RevId: 276097452 GitOrigin-RevId: e54b9c7bbb0c58475676c268e2e19c69f4bce48a Change-Id: I02d84454bb71ab21ad3d39650acf6cc6e36f58d7 --- absl/base/BUILD.bazel | 25 ++ absl/base/CMakeLists.txt | 26 ++ absl/base/config.h | 2 +- absl/base/internal/exponential_biased.cc | 84 +++++ absl/base/internal/exponential_biased.h | 77 ++++ absl/base/internal/exponential_biased_test.cc | 168 +++++++++ absl/base/optimization.h | 2 +- absl/container/BUILD.bazel | 1 + absl/container/CMakeLists.txt | 1 + absl/container/flat_hash_map.h | 2 +- absl/container/internal/hashtablez_sampler.cc | 83 +---- absl/container/internal/raw_hash_set.h | 20 +- absl/container/internal/raw_hash_set_test.cc | 2 +- absl/copts/AbseilConfigureCopts.cmake | 25 +- absl/random/BUILD.bazel | 2 +- absl/random/CMakeLists.txt | 17 +- absl/random/beta_distribution.h | 31 +- absl/random/beta_distribution_test.cc | 2 +- absl/random/exponential_distribution.h | 14 +- absl/random/gaussian_distribution.h | 22 +- absl/random/internal/BUILD.bazel | 16 +- absl/random/internal/distribution_impl.h | 194 ---------- absl/random/internal/distribution_impl_test.cc | 464 ----------------------- absl/random/internal/generate_real.h | 144 +++++++ absl/random/internal/generate_real_test.cc | 497 +++++++++++++++++++++++++ absl/random/log_uniform_int_distribution.h | 2 +- absl/random/poisson_distribution.h | 20 +- absl/random/uniform_int_distribution.h | 1 - absl/random/uniform_real_distribution.h | 15 +- 29 files changed, 1164 insertions(+), 795 deletions(-) create mode 100644 absl/base/internal/exponential_biased.cc create mode 100644 absl/base/internal/exponential_biased.h create mode 100644 absl/base/internal/exponential_biased_test.cc delete mode 100644 absl/random/internal/distribution_impl.h delete mode 100644 absl/random/internal/distribution_impl_test.cc create mode 100644 absl/random/internal/generate_real.h create mode 100644 absl/random/internal/generate_real_test.cc (limited to 'absl/base/config.h') diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index d74bac63..ffeca630 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -557,6 +557,31 @@ cc_test( ], ) +cc_library( + name = "exponential_biased", + srcs = ["internal/exponential_biased.cc"], + hdrs = ["internal/exponential_biased.h"], + linkopts = ABSL_DEFAULT_LINKOPTS, + visibility = [ + "//absl:__subpackages__", + ], + deps = [":core_headers"], +) + +cc_test( + name = "exponential_biased_test", + size = "small", + srcs = ["internal/exponential_biased_test.cc"], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + visibility = ["//visibility:private"], + deps = [ + ":exponential_biased", + "//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "scoped_set_env", testonly = 1, diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 79ee5b93..2698213c 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -503,6 +503,32 @@ absl_cc_test( gtest_main ) +absl_cc_library( + NAME + exponential_biased + SRCS + "internal/exponential_biased.cc" + HDRS + "internal/exponential_biased.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::core_headers +) + +absl_cc_test( + NAME + exponential_biased_test + SRCS + "internal/exponential_biased_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::exponential_biased + absl::strings + gmock_main +) + absl_cc_library( NAME scoped_set_env diff --git a/absl/base/config.h b/absl/base/config.h index 039b73d8..24851fa3 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -307,7 +307,7 @@ // ABSL_HAVE_SEMAPHORE_H // -// Checks whether the platform supports the header and sem_open(3) +// Checks whether the platform supports the header and sem_init(3) // family of functions as standardized in POSIX.1-2001. // // Note: While Apple provides for both iOS and macOS, it is diff --git a/absl/base/internal/exponential_biased.cc b/absl/base/internal/exponential_biased.cc new file mode 100644 index 00000000..d7ffd184 --- /dev/null +++ b/absl/base/internal/exponential_biased.cc @@ -0,0 +1,84 @@ +// 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. + +#include "absl/base/internal/exponential_biased.h" + +#include + +#include +#include +#include + +#include "absl/base/attributes.h" +#include "absl/base/optimization.h" + +namespace absl { +namespace base_internal { + +// The algorithm generates a random number between 0 and 1 and applies the +// inverse cumulative distribution function for an exponential. Specifically: +// Let m be the inverse of the sample period, then the probability +// distribution function is m*exp(-mx) so the CDF is +// p = 1 - exp(-mx), so +// q = 1 - p = exp(-mx) +// log_e(q) = -mx +// -log_e(q)/m = x +// log_2(q) * (-log_e(2) * 1/m) = x +// In the code, q is actually in the range 1 to 2**26, hence the -26 below +int64_t ExponentialBiased::Get(int64_t mean) { + if (ABSL_PREDICT_FALSE(!initialized_)) { + Initialize(); + } + + uint64_t rng = NextRandom(rng_); + rng_ = rng; + + // Take the top 26 bits as the random number + // (This plus the 1<<58 sampling bound give a max possible step of + // 5194297183973780480 bytes.) + // The uint32_t cast is to prevent a (hard-to-reproduce) NAN + // under piii debug for some binaries. + double q = static_cast(rng >> (kPrngNumBits - 26)) + 1.0; + // Put the computed p-value through the CDF of a geometric. + double interval = (std::log2(q) - 26) * (-std::log(2.0) * mean); + // Very large values of interval overflow int64_t. To avoid that, we will cheat + // and clamp any huge values to (int64_t max)/2. This is a potential source of + // bias, but the mean would need to be such a large value that it's not likely + // to come up. For example, with a mean of 1e18, the probability of hitting + // this condition is about 1/1000. For a mean of 1e17, standard calculators + // claim that this event won't happen. + if (interval > static_cast(std::numeric_limits::max() / 2)) { + return std::numeric_limits::max() / 2; + } + + return static_cast(interval); +} + +void ExponentialBiased::Initialize() { + // We don't get well distributed numbers from `this` so we call NextRandom() a + // bunch to mush the bits around. We use a global_rand to handle the case + // where the same thread (by memory address) gets created and destroyed + // repeatedly. + ABSL_CONST_INIT static std::atomic global_rand(0); + uint64_t r = reinterpret_cast(this) + + global_rand.fetch_add(1, std::memory_order_relaxed); + for (int i = 0; i < 20; ++i) { + r = NextRandom(r); + } + rng_ = r; + initialized_ = true; +} + +} // namespace base_internal +} // namespace absl diff --git a/absl/base/internal/exponential_biased.h b/absl/base/internal/exponential_biased.h new file mode 100644 index 00000000..cac2d8ad --- /dev/null +++ b/absl/base/internal/exponential_biased.h @@ -0,0 +1,77 @@ +// 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. + +#ifndef ABSL_BASE_INTERNAL_EXPONENTIAL_BIASED_H_ +#define ABSL_BASE_INTERNAL_EXPONENTIAL_BIASED_H_ + +#include + +namespace absl { +namespace base_internal { + +// ExponentialBiased provides a small and fast random number generator for a +// rounded exponential distribution. This generator doesn't requires very little +// state doesn't impose synchronization overhead, which makes it useful in some +// specialized scenarios. +// +// For the generated variable X, X ~ floor(Exponential(1/mean)). The floor +// operation introduces a small amount of bias, but the distribution is useful +// to generate a wait time. That is, if an operation is supposed to happen on +// average to 1/mean events, then the generated variable X will describe how +// many events to skip before performing the operation and computing a new X. +// +// The mathematically precise distribution to use for integer wait times is a +// Geometric distribution, but a Geometric distribution takes slightly more time +// to compute and when the mean is large (say, 100+), the Geometric distribution +// is hard to distinguish from the result of ExponentialBiased. +// +// This class is thread-compatible. +class ExponentialBiased { + public: + // The number of bits set by NextRandom. + static constexpr int kPrngNumBits = 48; + + // Generates the floor of an exponentially distributed random variable by + // rounding the value down to the nearest integer. The result will be in the + // range [0, int64_t max / 2]. + int64_t Get(int64_t mean); + + // Computes a random number in the range [0, 1<<(kPrngNumBits+1) - 1] + // + // This is public to enable testing. + static uint64_t NextRandom(uint64_t rnd); + + private: + void Initialize(); + + uint64_t rng_{0}; + bool initialized_{false}; +}; + +// Returns the next prng value. +// pRNG is: aX+b mod c with a = 0x5DEECE66D, b = 0xB, c = 1<<48 +// This is the lrand64 generator. +inline uint64_t ExponentialBiased::NextRandom(uint64_t rnd) { + const uint64_t prng_mult = uint64_t{0x5DEECE66D}; + const uint64_t prng_add = 0xB; + const uint64_t prng_mod_power = 48; + const uint64_t prng_mod_mask = + ~((~static_cast(0)) << prng_mod_power); + return (prng_mult * rnd + prng_add) & prng_mod_mask; +} + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_EXPONENTIAL_BIASED_H_ diff --git a/absl/base/internal/exponential_biased_test.cc b/absl/base/internal/exponential_biased_test.cc new file mode 100644 index 00000000..09b511d1 --- /dev/null +++ b/absl/base/internal/exponential_biased_test.cc @@ -0,0 +1,168 @@ +// 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. + +#include "absl/base/internal/exponential_biased.h" + +#include + +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/strings/str_cat.h" + +using ::testing::Ge; + +namespace absl { +namespace base_internal { + +MATCHER_P2(IsBetween, a, b, + absl::StrCat(std::string(negation ? "isn't" : "is"), " between ", a, + " and ", b)) { + return a <= arg && arg <= b; +} + +// Tests of the quality of the random numbers generated +// This uses the Anderson Darling test for uniformity. +// See "Evaluating the Anderson-Darling Distribution" by Marsaglia +// for details. + +// Short cut version of ADinf(z), z>0 (from Marsaglia) +// This returns the p-value for Anderson Darling statistic in +// the limit as n-> infinity. For finite n, apply the error fix below. +double AndersonDarlingInf(double z) { + if (z < 2) { + return exp(-1.2337141 / z) / sqrt(z) * + (2.00012 + + (0.247105 - + (0.0649821 - (0.0347962 - (0.011672 - 0.00168691 * z) * z) * z) * + z) * + z); + } + return exp( + -exp(1.0776 - + (2.30695 - + (0.43424 - (0.082433 - (0.008056 - 0.0003146 * z) * z) * z) * z) * + z)); +} + +// Corrects the approximation error in AndersonDarlingInf for small values of n +// Add this to AndersonDarlingInf to get a better approximation +// (from Marsaglia) +double AndersonDarlingErrFix(int n, double x) { + if (x > 0.8) { + return (-130.2137 + + (745.2337 - + (1705.091 - (1950.646 - (1116.360 - 255.7844 * x) * x) * x) * x) * + x) / + n; + } + double cutoff = 0.01265 + 0.1757 / n; + if (x < cutoff) { + double t = x / cutoff; + t = sqrt(t) * (1 - t) * (49 * t - 102); + return t * (0.0037 / (n * n) + 0.00078 / n + 0.00006) / n; + } else { + double t = (x - cutoff) / (0.8 - cutoff); + t = -0.00022633 + + (6.54034 - (14.6538 - (14.458 - (8.259 - 1.91864 * t) * t) * t) * t) * + t; + return t * (0.04213 + 0.01365 / n) / n; + } +} + +// Returns the AndersonDarling p-value given n and the value of the statistic +double AndersonDarlingPValue(int n, double z) { + double ad = AndersonDarlingInf(z); + double errfix = AndersonDarlingErrFix(n, ad); + return ad + errfix; +} + +double AndersonDarlingStatistic(const std::vector& random_sample) { + int n = random_sample.size(); + double ad_sum = 0; + for (int i = 0; i < n; i++) { + ad_sum += (2 * i + 1) * + std::log(random_sample[i] * (1 - random_sample[n - 1 - i])); + } + double ad_statistic = -n - 1 / static_cast(n) * ad_sum; + return ad_statistic; +} + +// Tests if the array of doubles is uniformly distributed. +// Returns the p-value of the Anderson Darling Statistic +// for the given set of sorted random doubles +// See "Evaluating the Anderson-Darling Distribution" by +// Marsaglia and Marsaglia for details. +double AndersonDarlingTest(const std::vector& random_sample) { + double ad_statistic = AndersonDarlingStatistic(random_sample); + double p = AndersonDarlingPValue(random_sample.size(), ad_statistic); + return p; +} + +// Testing that NextRandom generates uniform random numbers. Applies the +// Anderson-Darling test for uniformity +TEST(ExponentialBiasedTest, TestNextRandom) { + for (auto n : std::vector({ + 10, // Check short-range correlation + 100, 1000, + 10000 // Make sure there's no systemic error + })) { + uint64_t x = 1; + // This assumes that the prng returns 48 bit numbers + uint64_t max_prng_value = static_cast(1) << 48; + // Initialize. + for (int i = 1; i <= 20; i++) { + x = ExponentialBiased::NextRandom(x); + } + std::vector int_random_sample(n); + // Collect samples + for (int i = 0; i < n; i++) { + int_random_sample[i] = x; + x = ExponentialBiased::NextRandom(x); + } + // First sort them... + std::sort(int_random_sample.begin(), int_random_sample.end()); + std::vector random_sample(n); + // Convert them to uniform randoms (in the range [0,1]) + for (int i = 0; i < n; i++) { + random_sample[i] = + static_cast(int_random_sample[i]) / max_prng_value; + } + // Now compute the Anderson-Darling statistic + double ad_pvalue = AndersonDarlingTest(random_sample); + EXPECT_GT(std::min(ad_pvalue, 1 - ad_pvalue), 0.0001) + << "prng is not uniform: n = " << n << " p = " << ad_pvalue; + } +} + +// The generator needs to be available as a thread_local and as a static +// variable. +TEST(ExponentialBiasedTest, InitializationModes) { + ABSL_CONST_INIT static ExponentialBiased eb_static; + EXPECT_THAT(eb_static.Get(2), Ge(0)); + +#if ABSL_HAVE_THREAD_LOCAL + thread_local ExponentialBiased eb_thread; + EXPECT_THAT(eb_thread.Get(2), Ge(0)); +#endif + + ExponentialBiased eb_stack; + EXPECT_THAT(eb_stack.Get(2), Ge(0)); +} + +} // namespace base_internal +} // namespace absl diff --git a/absl/base/optimization.h b/absl/base/optimization.h index 0dcbef32..646523b3 100644 --- a/absl/base/optimization.h +++ b/absl/base/optimization.h @@ -172,7 +172,7 @@ #if ABSL_HAVE_BUILTIN(__builtin_expect) || \ (defined(__GNUC__) && !defined(__clang__)) #define ABSL_PREDICT_FALSE(x) (__builtin_expect(x, 0)) -#define ABSL_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#define ABSL_PREDICT_TRUE(x) (__builtin_expect(false || (x), true)) #else #define ABSL_PREDICT_FALSE(x) (x) #define ABSL_PREDICT_TRUE(x) (x) diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 0894bb20..e60979b2 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -493,6 +493,7 @@ cc_library( ":have_sse", "//absl/base", "//absl/base:core_headers", + "//absl/base:exponential_biased", "//absl/debugging:stacktrace", "//absl/memory", "//absl/synchronization", diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 933c7a8c..aa33659b 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -538,6 +538,7 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} DEPS absl::base + absl::exponential_biased absl::have_sse absl::synchronization ) diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h index 5c16ac88..283f2439 100644 --- a/absl/container/flat_hash_map.h +++ b/absl/container/flat_hash_map.h @@ -401,7 +401,7 @@ class flat_hash_map : public absl::container_internal::raw_hash_map< // for the past-the-end iterator, which is invalidated. // // `swap()` requires that the flat hash map's hashing and key equivalence - // functions be Swappable, and are exchaged using unqualified calls to + // functions be Swappable, and are exchanged using unqualified calls to // non-member `swap()`. If the map's allocator has // `std::allocator_traits::propagate_on_container_swap::value` // set to `true`, the allocators are also exchanged using an unqualified call diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 054e8981..0a7ef61c 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -21,6 +21,7 @@ #include #include "absl/base/attributes.h" +#include "absl/base/internal/exponential_biased.h" #include "absl/container/internal/have_sse.h" #include "absl/debugging/stacktrace.h" #include "absl/memory/memory.h" @@ -37,77 +38,13 @@ ABSL_CONST_INIT std::atomic g_hashtablez_enabled{ ABSL_CONST_INIT std::atomic g_hashtablez_sample_parameter{1 << 10}; ABSL_CONST_INIT std::atomic g_hashtablez_max_samples{1 << 20}; -// Returns the next pseudo-random value. -// pRNG is: aX+b mod c with a = 0x5DEECE66D, b = 0xB, c = 1<<48 -// This is the lrand64 generator. -uint64_t NextRandom(uint64_t rnd) { - const uint64_t prng_mult = uint64_t{0x5DEECE66D}; - const uint64_t prng_add = 0xB; - const uint64_t prng_mod_power = 48; - const uint64_t prng_mod_mask = ~(~uint64_t{0} << prng_mod_power); - return (prng_mult * rnd + prng_add) & prng_mod_mask; -} - -// Generates a geometric variable with the specified mean. -// This is done by generating a random number between 0 and 1 and applying -// the inverse cumulative distribution function for an exponential. -// Specifically: Let m be the inverse of the sample period, then -// the probability distribution function is m*exp(-mx) so the CDF is -// p = 1 - exp(-mx), so -// q = 1 - p = exp(-mx) -// log_e(q) = -mx -// -log_e(q)/m = x -// log_2(q) * (-log_e(2) * 1/m) = x -// In the code, q is actually in the range 1 to 2**26, hence the -26 below -// -int64_t GetGeometricVariable(int64_t mean) { #if ABSL_HAVE_THREAD_LOCAL - thread_local -#else // ABSL_HAVE_THREAD_LOCAL - // SampleSlow and hence GetGeometricVariable is guarded by a single mutex when - // there are not thread locals. Thus, a single global rng is acceptable for - // that case. - static -#endif // ABSL_HAVE_THREAD_LOCAL - uint64_t rng = []() { - // We don't get well distributed numbers from this so we call - // NextRandom() a bunch to mush the bits around. We use a global_rand - // to handle the case where the same thread (by memory address) gets - // created and destroyed repeatedly. - ABSL_CONST_INIT static std::atomic global_rand(0); - uint64_t r = reinterpret_cast(&rng) + - global_rand.fetch_add(1, std::memory_order_relaxed); - for (int i = 0; i < 20; ++i) { - r = NextRandom(r); - } - return r; - }(); - - rng = NextRandom(rng); - - // Take the top 26 bits as the random number - // (This plus the 1<<58 sampling bound give a max possible step of - // 5194297183973780480 bytes.) - const uint64_t prng_mod_power = 48; // Number of bits in prng - // The uint32_t cast is to prevent a (hard-to-reproduce) NAN - // under piii debug for some binaries. - double q = static_cast(rng >> (prng_mod_power - 26)) + 1.0; - // Put the computed p-value through the CDF of a geometric. - double interval = (log2(q) - 26) * (-std::log(2.0) * mean); - - // Very large values of interval overflow int64_t. If we happen to - // hit such improbable condition, we simply cheat and clamp interval - // to largest supported value. - if (interval > static_cast(std::numeric_limits::max() / 2)) { - return std::numeric_limits::max() / 2; - } - - // Small values of interval are equivalent to just sampling next time. - if (interval < 1) { - return 1; - } - return static_cast(interval); -} +thread_local absl::base_internal::ExponentialBiased + g_exponential_biased_generator; +#else +ABSL_CONST_INIT static absl::base_internal::ExponentialBiased + g_exponential_biased_generator; +#endif } // namespace @@ -253,8 +190,12 @@ HashtablezInfo* SampleSlow(int64_t* next_sample) { } bool first = *next_sample < 0; - *next_sample = GetGeometricVariable( + *next_sample = g_exponential_biased_generator.Get( g_hashtablez_sample_parameter.load(std::memory_order_relaxed)); + // Small values of interval are equivalent to just sampling next time. + if (*next_sample < 1) { + *next_sample = 1; + } // g_hashtablez_enabled can be dynamically flipped, we need to set a threshold // low enough that we will start sampling in a reasonable time, so we just use diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 42b3c468..9992ba4b 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -614,13 +614,17 @@ class raw_hash_set { iterator() {} // PRECONDITION: not an end() iterator. - reference operator*() const { return PolicyTraits::element(slot_); } + reference operator*() const { + /* To be enabled: assert_is_full(); */ + return PolicyTraits::element(slot_); + } // PRECONDITION: not an end() iterator. pointer operator->() const { return &operator*(); } // PRECONDITION: not an end() iterator. iterator& operator++() { + /* To be enabled: assert_is_full(); */ ++ctrl_; ++slot_; skip_empty_or_deleted(); @@ -634,6 +638,8 @@ class raw_hash_set { } friend bool operator==(const iterator& a, const iterator& b) { + /* To be enabled: a.assert_is_valid(); */ + /* To be enabled: b.assert_is_valid(); */ return a.ctrl_ == b.ctrl_; } friend bool operator!=(const iterator& a, const iterator& b) { @@ -644,6 +650,11 @@ class raw_hash_set { iterator(ctrl_t* ctrl) : ctrl_(ctrl) {} // for end() iterator(ctrl_t* ctrl, slot_type* slot) : ctrl_(ctrl), slot_(slot) {} + void assert_is_full() const { assert(IsFull(*ctrl_)); } + void assert_is_valid() const { + assert(!ctrl_ || IsFull(*ctrl_) || *ctrl_ == kSentinel); + } + void skip_empty_or_deleted() { while (IsEmptyOrDeleted(*ctrl_)) { // ctrl is not necessarily aligned to Group::kWidth. It is also likely @@ -1155,7 +1166,7 @@ class raw_hash_set { // This overload is necessary because otherwise erase(const K&) would be // a better match if non-const iterator is passed as an argument. void erase(iterator it) { - assert(it != end()); + it.assert_is_full(); PolicyTraits::destroy(&alloc_ref(), it.slot_); erase_meta_only(it); } @@ -1172,12 +1183,14 @@ class raw_hash_set { template void merge(raw_hash_set& src) { // NOLINT assert(this != &src); - for (auto it = src.begin(), e = src.end(); it != e; ++it) { + for (auto it = src.begin(), e = src.end(); it != e;) { + auto next = std::next(it); if (PolicyTraits::apply(InsertSlot{*this, std::move(*it.slot_)}, PolicyTraits::element(it.slot_)) .second) { src.erase_meta_only(it); } + it = next; } } @@ -1187,6 +1200,7 @@ class raw_hash_set { } node_type extract(const_iterator position) { + position.inner_.assert_is_full(); auto node = CommonAccess::Transfer(alloc_ref(), position.inner_.slot_); erase_meta_only(position); diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index ed4ca8c8..33cfa72c 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -1837,7 +1837,7 @@ TEST(TableDeathTest, EraseOfEndAsserts) { IntTable t; // Extra simple "regexp" as regexp support is highly varied across platforms. - constexpr char kDeathMsg[] = "it != end"; + constexpr char kDeathMsg[] = "IsFull"; EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg); } diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake index b430873c..b4426469 100644 --- a/absl/copts/AbseilConfigureCopts.cmake +++ b/absl/copts/AbseilConfigureCopts.cmake @@ -5,10 +5,29 @@ set(ABSL_LSAN_LINKOPTS "") set(ABSL_HAVE_LSAN OFF) set(ABSL_DEFAULT_LINKOPTS "") +if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") + if (MSVC) + set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}") + else() + set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_X64_FLAGS}") + endif() +elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "arm") + if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") + set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_ARM64_FLAGS}") + elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") + set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_ARM32_FLAGS}") + else() + message(WARNING "Value of CMAKE_SIZEOF_VOID_P (${CMAKE_SIZEOF_VOID_P}) is not supported.") + endif() +else() + message(WARNING "Value of CMAKE_SYSTEM_PROCESSOR (${CMAKE_SYSTEM_PROCESSOR}) is unknown and cannot be used to set ABSL_RANDOM_RANDEN_COPTS") + set(ABSL_RANDOM_RANDEN_COPTS "") +endif() + + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(ABSL_DEFAULT_COPTS "${ABSL_GCC_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_GCC_FLAGS};${ABSL_GCC_TEST_FLAGS}") - set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_X64_FLAGS}") elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # MATCHES so we get both Clang and AppleClang if(MSVC) @@ -16,11 +35,9 @@ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(ABSL_DEFAULT_COPTS "${ABSL_CLANG_CL_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_CLANG_CL_FLAGS};${ABSL_CLANG_CL_TEST_FLAGS}") set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}") - set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}") else() set(ABSL_DEFAULT_COPTS "${ABSL_LLVM_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_LLVM_FLAGS};${ABSL_LLVM_TEST_FLAGS}") - set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_X64_FLAGS}") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # AppleClang doesn't have lsan # https://developer.apple.com/documentation/code_diagnostics @@ -34,12 +51,10 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(ABSL_DEFAULT_COPTS "${ABSL_MSVC_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_MSVC_FLAGS};${ABSL_MSVC_TEST_FLAGS}") set(ABSL_DEFAULT_LINKOPTS "${ABSL_MSVC_LINKOPTS}") - set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}") else() message(WARNING "Unknown compiler: ${CMAKE_CXX_COMPILER}. Building with no default flags") set(ABSL_DEFAULT_COPTS "") set(ABSL_TEST_COPTS "") - set(ABSL_RANDOM_RANDEN_COPTS "") endif() if("${CMAKE_CXX_STANDARD}" EQUAL 98) diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index 828f1348..c3520df8 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -69,10 +69,10 @@ cc_library( "//absl/base:base_internal", "//absl/base:core_headers", "//absl/meta:type_traits", - "//absl/random/internal:distribution_impl", "//absl/random/internal:distributions", "//absl/random/internal:fast_uniform_bits", "//absl/random/internal:fastmath", + "//absl/random/internal:generate_real", "//absl/random/internal:iostream_state_saver", "//absl/random/internal:traits", "//absl/random/internal:uniform_helper", diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 19dd2cab..289854ff 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -58,7 +58,7 @@ absl_cc_library( DEPS absl::base_internal absl::core_headers - absl::random_internal_distribution_impl + absl::random_internal_generate_real absl::random_internal_distributions absl::random_internal_fast_uniform_bits absl::random_internal_fastmath @@ -543,19 +543,18 @@ absl_cc_library( # Internal-only target, do not depend on directly. absl_cc_library( NAME - random_internal_distribution_impl + random_internal_generate_real HDRS - "internal/distribution_impl.h" + "internal/generate_real.h" COPTS ${ABSL_DEFAULT_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS absl::bits - absl::config - absl::int128 absl::random_internal_fastmath absl::random_internal_traits + absl::type_traits ) # Internal-only target, do not depend on directly. @@ -767,9 +766,9 @@ absl_cc_test( # Internal-only target, do not depend on directly. absl_cc_test( NAME - random_internal_distribution_impl_test + random_internal_generate_real_test SRCS - "internal/distribution_impl_test.cc" + "internal/generate_real_test.cc" COPTS ${ABSL_TEST_COPTS} LINKOPTS @@ -777,8 +776,7 @@ absl_cc_test( DEPS absl::bits absl::flags - absl::int128 - absl::random_internal_distribution_impl + absl::random_internal_generate_real gtest_main ) @@ -1029,7 +1027,6 @@ absl_cc_library( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::core_headers - absl::random_internal_distribution_impl absl::random_internal_fast_uniform_bits absl::random_internal_iostream_state_saver absl::random_internal_traits diff --git a/absl/random/beta_distribution.h b/absl/random/beta_distribution.h index e29894f2..b09b02f0 100644 --- a/absl/random/beta_distribution.h +++ b/absl/random/beta_distribution.h @@ -22,9 +22,10 @@ #include #include -#include "absl/random/internal/distribution_impl.h" +#include "absl/meta/type_traits.h" #include "absl/random/internal/fast_uniform_bits.h" #include "absl/random/internal/fastmath.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" namespace absl { @@ -275,15 +276,21 @@ typename beta_distribution::result_type beta_distribution::AlgorithmJoehnk( URBG& g, // NOLINT(runtime/references) const param_type& p) { + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + using real_type = + absl::conditional_t::value, float, double>; + // Based on Joehnk, M. D. Erzeugung von betaverteilten und gammaverteilten // Zufallszahlen. Metrika 8.1 (1964): 5-15. // This method is described in Knuth, Vol 2 (Third Edition), pp 134. - using RandU64ToReal = typename random_internal::RandU64ToReal; - using random_internal::PositiveValueT; + result_type u, v, x, y, z; for (;;) { - u = RandU64ToReal::template Value(fast_u64_(g)); - v = RandU64ToReal::template Value(fast_u64_(g)); + u = GenerateRealFromBits( + fast_u64_(g)); + v = GenerateRealFromBits( + fast_u64_(g)); // Direct method. std::pow is slow for float, so rely on the optimizer to // remove the std::pow() path for that case. @@ -327,12 +334,14 @@ typename beta_distribution::result_type beta_distribution::AlgorithmCheng( URBG& g, // NOLINT(runtime/references) const param_type& p) { + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + using real_type = + absl::conditional_t::value, float, double>; + // Based on Cheng, Russell CH. Generating beta variates with nonintegral // shape parameters. Communications of the ACM 21.4 (1978): 317-322. // (https://dl.acm.org/citation.cfm?id=359482). - using RandU64ToReal = typename random_internal::RandU64ToReal; - using random_internal::PositiveValueT; - static constexpr result_type kLogFour = result_type(1.3862943611198906188344642429163531361); // log(4) static constexpr result_type kS = @@ -341,8 +350,10 @@ beta_distribution::AlgorithmCheng( const bool use_algorithm_ba = (p.method_ == param_type::CHENG_BA); result_type u1, u2, v, w, z, r, s, t, bw_inv, lhs; for (;;) { - u1 = RandU64ToReal::template Value(fast_u64_(g)); - u2 = RandU64ToReal::template Value(fast_u64_(g)); + u1 = GenerateRealFromBits( + fast_u64_(g)); + u2 = GenerateRealFromBits( + fast_u64_(g)); v = p.y_ * std::log(u1 / (1 - u1)); w = p.a_ * std::exp(v); bw_inv = result_type(1) / (p.b_ + w); diff --git a/absl/random/beta_distribution_test.cc b/absl/random/beta_distribution_test.cc index 966ad08b..d0111b3e 100644 --- a/absl/random/beta_distribution_test.cc +++ b/absl/random/beta_distribution_test.cc @@ -92,7 +92,7 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest) { for (TypeParam alpha : kValues) { for (TypeParam beta : kValues) { ABSL_INTERNAL_LOG( - INFO, absl::StrFormat("Smoke test for Beta(%f, %f)", alpha, beta)); + INFO, absl::StrFormat("Smoke test for Beta(%a, %a)", alpha, beta)); param_type param(alpha, beta); absl::beta_distribution before(alpha, beta); diff --git a/absl/random/exponential_distribution.h b/absl/random/exponential_distribution.h index c8af1975..24abf57e 100644 --- a/absl/random/exponential_distribution.h +++ b/absl/random/exponential_distribution.h @@ -21,8 +21,9 @@ #include #include -#include "absl/random/internal/distribution_impl.h" +#include "absl/meta/type_traits.h" #include "absl/random/internal/fast_uniform_bits.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" namespace absl { @@ -118,9 +119,14 @@ typename exponential_distribution::result_type exponential_distribution::operator()( URBG& g, // NOLINT(runtime/references) const param_type& p) { - using random_internal::NegativeValueT; - const result_type u = random_internal::RandU64ToReal< - result_type>::template Value(fast_u64_(g)); + using random_internal::GenerateNegativeTag; + using random_internal::GenerateRealFromBits; + using real_type = + absl::conditional_t::value, float, double>; + + const result_type u = GenerateRealFromBits(fast_u64_(g)); // U(-1, 0) + // log1p(-x) is mathematically equivalent to log(1 - x) but has more // accuracy for x near zero. return p.neg_inv_lambda_ * std::log1p(u); diff --git a/absl/random/gaussian_distribution.h b/absl/random/gaussian_distribution.h index 1d1347bc..c299e944 100644 --- a/absl/random/gaussian_distribution.h +++ b/absl/random/gaussian_distribution.h @@ -28,8 +28,8 @@ #include #include -#include "absl/random/internal/distribution_impl.h" #include "absl/random/internal/fast_uniform_bits.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" namespace absl { @@ -207,12 +207,18 @@ namespace random_internal { template inline double gaussian_distribution_base::zignor_fallback(URBG& g, bool neg) { + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + // This fallback path happens approximately 0.05% of the time. double x, y; do { // kRInv = 1/r, U(0, 1) - x = kRInv * std::log(RandU64ToDouble(fast_u64_(g))); - y = -std::log(RandU64ToDouble(fast_u64_(g))); + x = kRInv * + std::log(GenerateRealFromBits( + fast_u64_(g))); + y = -std::log( + GenerateRealFromBits(fast_u64_(g))); } while ((y + y) < (x * x)); return neg ? (x - kR) : (kR - x); } @@ -220,6 +226,10 @@ inline double gaussian_distribution_base::zignor_fallback(URBG& g, bool neg) { template inline double gaussian_distribution_base::zignor( URBG& g) { // NOLINT(runtime/references) + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + using random_internal::GenerateSignedTag; + while (true) { // We use a single uint64_t to generate both a double and a strip. // These bits are unused when the generated double is > 1/2^5. @@ -227,7 +237,8 @@ inline double gaussian_distribution_base::zignor( // values (those smaller than 1/2^5, which all end up on the left tail). uint64_t bits = fast_u64_(g); int i = static_cast(bits & kMask); // pick a random strip - double j = RandU64ToDouble(bits); // U(-1, 1) + double j = GenerateRealFromBits( + bits); // U(-1, 1) const double x = j * zg_.x[i]; // Retangular box. Handles >97% of all cases. @@ -244,7 +255,8 @@ inline double gaussian_distribution_base::zignor( } // i > 0: Wedge samples using precomputed values. - double v = RandU64ToDouble(fast_u64_(g)); // U(0, 1) + double v = GenerateRealFromBits( + fast_u64_(g)); // U(0, 1) if ((zg_.f[i + 1] + v * (zg_.f[i] - zg_.f[i + 1])) < std::exp(-0.5 * x * x)) { return x; diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index ec58cecd..91388d19 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -175,9 +175,9 @@ cc_library( ) cc_library( - name = "distribution_impl", + name = "generate_real", hdrs = [ - "distribution_impl.h", + "generate_real.h", ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, @@ -185,8 +185,7 @@ cc_library( ":fastmath", ":traits", "//absl/base:bits", - "//absl/base:config", - "//absl/numeric:int128", + "//absl/meta:type_traits", ], ) @@ -398,16 +397,17 @@ cc_test( ) cc_test( - name = "distribution_impl_test", + name = "generate_real_test", size = "small", - srcs = ["distribution_impl_test.cc"], + srcs = [ + "generate_real_test.cc", + ], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ - ":distribution_impl", + ":generate_real", "//absl/base:bits", "//absl/flags:flag", - "//absl/numeric:int128", "@com_google_googletest//:gtest_main", ], ) diff --git a/absl/random/internal/distribution_impl.h b/absl/random/internal/distribution_impl.h deleted file mode 100644 index 49b3e1a6..00000000 --- a/absl/random/internal/distribution_impl.h +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2017 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. - -#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTION_IMPL_H_ -#define ABSL_RANDOM_INTERNAL_DISTRIBUTION_IMPL_H_ - -// This file contains some implementation details which are used by one or more -// of the absl random number distributions. - -#include -#include -#include -#include -#include -#include - -#if (defined(_WIN32) || defined(_WIN64)) && defined(_M_IA64) -#include // NOLINT(build/include_order) -#pragma intrinsic(_umul128) -#define ABSL_INTERNAL_USE_UMUL128 1 -#endif - -#include "absl/base/config.h" -#include "absl/base/internal/bits.h" -#include "absl/numeric/int128.h" -#include "absl/random/internal/fastmath.h" -#include "absl/random/internal/traits.h" - -namespace absl { -namespace random_internal { - -// Creates a double from `bits`, with the template fields controlling the -// output. -// -// RandU64To is both more efficient and generates more unique values in the -// result interval than known implementations of std::generate_canonical(). -// -// The `Signed` parameter controls whether positive, negative, or both are -// returned (thus affecting the output interval). -// When Signed == SignedValueT, range is U(-1, 1) -// When Signed == NegativeValueT, range is U(-1, 0) -// When Signed == PositiveValueT, range is U(0, 1) -// -// When the `IncludeZero` parameter is true, the function may return 0 for some -// inputs, otherwise it never returns 0. -// -// The `ExponentBias` parameter determines the scale of the output range by -// adjusting the exponent. -// -// When a value in U(0,1) is required, use: -// RandU64ToDouble(); -// -// When a value in U(-1,1) is required, use: -// RandU64ToDouble() => U(-1, 1) -// This generates more distinct values than the mathematically equivalent -// expression `U(0, 1) * 2.0 - 1.0`, and is preferable. -// -// Scaling the result by powers of 2 (and avoiding a multiply) is also possible: -// RandU64ToDouble(); => U(0, 2) -// RandU64ToDouble(); => U(0, 0.5) -// - -// Tristate types controlling the output. -struct PositiveValueT {}; -struct NegativeValueT {}; -struct SignedValueT {}; - -// RandU64ToDouble is the double-result variant of RandU64To, described above. -template -inline double RandU64ToDouble(uint64_t bits) { - static_assert(std::is_same::value || - std::is_same::value || - std::is_same::value, - ""); - - // Maybe use the left-most bit for a sign bit. - uint64_t sign = std::is_same::value - ? 0x8000000000000000ull - : 0; // Sign bits. - - if (std::is_same::value) { - sign = bits & 0x8000000000000000ull; - bits = bits & 0x7FFFFFFFFFFFFFFFull; - } - if (IncludeZero) { - if (bits == 0u) return 0; - } - - // Number of leading zeros is mapped to the exponent: 2^-clz - int clz = base_internal::CountLeadingZeros64(bits); - // Shift number left to erase leading zeros. - bits <<= IncludeZero ? clz : (clz & 63); - - // Shift number right to remove bits that overflow double mantissa. The - // direction of the shift depends on `clz`. - bits >>= (64 - DBL_MANT_DIG); - - // Compute IEEE 754 double exponent. - // In the Signed case, bits is a 63-bit number with a 0 msb. Adjust the - // exponent to account for that. - const uint64_t exp = - (std::is_same::value ? 1023U : 1022U) + - static_cast(ExponentBias - clz); - constexpr int kExp = DBL_MANT_DIG - 1; - // Construct IEEE 754 double from exponent and mantissa. - const uint64_t val = sign | (exp << kExp) | (bits & ((1ULL << kExp) - 1U)); - - double res; - static_assert(sizeof(res) == sizeof(val), "double is not 64 bit"); - // Memcpy value from "val" to "res" to avoid aliasing problems. Assumes that - // endian-ness is same for double and uint64_t. - std::memcpy(&res, &val, sizeof(res)); - - return res; -} - -// RandU64ToFloat is the float-result variant of RandU64To, described above. -template -inline float RandU64ToFloat(uint64_t bits) { - static_assert(std::is_same::value || - std::is_same::value || - std::is_same::value, - ""); - - // Maybe use the left-most bit for a sign bit. - uint64_t sign = std::is_same::value - ? 0x80000000ul - : 0; // Sign bits. - - if (std::is_same::value) { - uint64_t a = bits & 0x8000000000000000ull; - sign = static_cast(a >> 32); - bits = bits & 0x7FFFFFFFFFFFFFFFull; - } - if (IncludeZero) { - if (bits == 0u) return 0; - } - - // Number of leading zeros is mapped to the exponent: 2^-clz - int clz = base_internal::CountLeadingZeros64(bits); - // Shift number left to erase leading zeros. - bits <<= IncludeZero ? clz : (clz & 63); - // Shift number right to remove bits that overflow double mantissa. The - // direction of the shift depends on `clz`. - bits >>= (64 - FLT_MANT_DIG); - - // Construct IEEE 754 float exponent. - // In the Signed case, bits is a 63-bit number with a 0 msb. Adjust the - // exponent to account for that. - const uint32_t exp = - (std::is_same::value ? 127U : 126U) + - static_cast(ExponentBias - clz); - constexpr int kExp = FLT_MANT_DIG - 1; - const uint32_t val = sign | (exp << kExp) | (bits & ((1U << kExp) - 1U)); - - float res; - static_assert(sizeof(res) == sizeof(val), "float is not 32 bit"); - // Assumes that endian-ness is same for float and uint32_t. - std::memcpy(&res, &val, sizeof(res)); - - return res; -} - -template -struct RandU64ToReal { - template - static inline Result Value(uint64_t bits) { - return RandU64ToDouble(bits); - } -}; - -template <> -struct RandU64ToReal { - template - static inline float Value(uint64_t bits) { - return RandU64ToFloat(bits); - } -}; - -} // namespace random_internal -} // namespace absl - -#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_IMPL_H_ diff --git a/absl/random/internal/distribution_impl_test.cc b/absl/random/internal/distribution_impl_test.cc deleted file mode 100644 index fcc16904..00000000 --- a/absl/random/internal/distribution_impl_test.cc +++ /dev/null @@ -1,464 +0,0 @@ -// Copyright 2017 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. - -#include "absl/random/internal/distribution_impl.h" - -#include "gtest/gtest.h" -#include "absl/base/internal/bits.h" -#include "absl/flags/flag.h" -#include "absl/numeric/int128.h" - -ABSL_FLAG(int64_t, absl_random_test_trials, 50000, - "Number of trials for the probability tests."); - -using absl::random_internal::NegativeValueT; -using absl::random_internal::PositiveValueT; -using absl::random_internal::RandU64ToDouble; -using absl::random_internal::RandU64ToFloat; -using absl::random_internal::SignedValueT; - -namespace { - -TEST(DistributionImplTest, U64ToFloat_Positive_NoZero_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 2.710505431e-20f); - EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0.5); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloat_Positive_Zero_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 0.0); - EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0.5); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloat_Negative_NoZero_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), -2.710505431e-20f); - EXPECT_EQ(ToFloat(0x0000000000000001), -5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000000), -0.5); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloat_Signed_NoZero_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 5.421010862e-20f); - EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f); - EXPECT_EQ(ToFloat(0x8000000000000000), -5.421010862e-20f); - EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloat_Signed_Zero_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 0); - EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0); - EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloat_Signed_Bias_Test) { - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - EXPECT_EQ(ToFloat(0x0000000000000000), 0); - EXPECT_EQ(ToFloat(0x0000000000000001), 2 * 1.084202172e-19f); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 2 * 0.9999999404f); - EXPECT_EQ(ToFloat(0x8000000000000000), 0); - EXPECT_EQ(ToFloat(0x8000000000000001), 2 * -1.084202172e-19f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 2 * -0.9999999404f); -} - -TEST(DistributionImplTest, U64ToFloatTest) { - auto ToFloat = [](uint64_t a) -> float { - return RandU64ToFloat(a); - }; - - EXPECT_EQ(ToFloat(0x0000000000000000), 0.0f); - - EXPECT_EQ(ToFloat(0x8000000000000000), 0.5f); - EXPECT_EQ(ToFloat(0x8000000000000001), 0.5f); - EXPECT_EQ(ToFloat(0x800000FFFFFFFFFF), 0.5f); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); - - EXPECT_GT(ToFloat(0x0000000000000001), 0.0f); - - EXPECT_NE(ToFloat(0x7FFFFF0000000000), ToFloat(0x7FFFFEFFFFFFFFFF)); - - EXPECT_LT(ToFloat(0xFFFFFFFFFFFFFFFF), 1.0f); - int32_t two_to_24 = 1 << 24; - EXPECT_EQ(static_cast(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24), - two_to_24 - 1); - EXPECT_NE(static_cast(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24 * 2), - two_to_24 * 2 - 1); - EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFF0000000000)); - EXPECT_NE(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFEFFFFFFFFFF)); - EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF8000000000)); - EXPECT_NE(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF7FFFFFFFFF)); - EXPECT_EQ(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFC000000000)); - EXPECT_NE(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFBFFFFFFFFF)); - - // For values where every bit counts, the values scale as multiples of the - // input. - for (int i = 0; i < 100; ++i) { - EXPECT_EQ(i * ToFloat(0x0000000000000001), ToFloat(i)); - } - - // For each i: value generated from (1 << i). - float exp_values[64]; - exp_values[63] = 0.5f; - for (int i = 62; i >= 0; --i) exp_values[i] = 0.5f * exp_values[i + 1]; - constexpr uint64_t one = 1; - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(ToFloat(one << i), exp_values[i]); - for (int j = 1; j < FLT_MANT_DIG && i - j >= 0; ++j) { - EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToFloat((one << i) + (one << (i - j))), - exp_values[i] + exp_values[i - j]); - } - for (int j = FLT_MANT_DIG; i - j >= 0; ++j) { - EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToFloat((one << i) + (one << (i - j))), exp_values[i]); - } - } -} - -TEST(DistributionImplTest, U64ToDouble_Positive_NoZero_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 2.710505431213761085e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000002), 1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); -} - -TEST(DistributionImplTest, U64ToDouble_Positive_Zero_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); - EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); -} - -TEST(DistributionImplTest, U64ToDouble_Negative_NoZero_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), -2.710505431213761085e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), -5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000002), -1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x8000000000000000), -0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); -} - -TEST(DistributionImplTest, U64ToDouble_Signed_NoZero_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978); - EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); -} - -TEST(DistributionImplTest, U64ToDouble_Signed_Zero_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - EXPECT_EQ(ToDouble(0x0000000000000000), 0); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978); - EXPECT_EQ(ToDouble(0x8000000000000000), 0); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); -} - -TEST(DistributionImplTest, U64ToDouble_Signed_Bias_Test) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - EXPECT_EQ(ToDouble(0x0000000000000000), 0); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19 / 2); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978 / 2); - EXPECT_EQ(ToDouble(0x8000000000000000), 0); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19 / 2); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978 / 2); -} - -TEST(DistributionImplTest, U64ToDoubleTest) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); - EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); - - EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x7fffffffffffffef), 0.499999999999999944489); - EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); - - // For values > 0.5, RandU64ToDouble discards up to 11 bits. (64-53). - EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x80000000000007FF), 0.5); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF)); - - EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFF), 1.0); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF800)); - EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF7FF)); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00)); - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFBFF)); - EXPECT_EQ(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFE00)); - EXPECT_NE(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFDFF)); - - EXPECT_EQ(ToDouble(0x1000000000000001), 0.0625); - EXPECT_EQ(ToDouble(0x2000000000000001), 0.125); - EXPECT_EQ(ToDouble(0x3000000000000001), 0.1875); - EXPECT_EQ(ToDouble(0x4000000000000001), 0.25); - EXPECT_EQ(ToDouble(0x5000000000000001), 0.3125); - EXPECT_EQ(ToDouble(0x6000000000000001), 0.375); - EXPECT_EQ(ToDouble(0x7000000000000001), 0.4375); - EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x9000000000000001), 0.5625); - EXPECT_EQ(ToDouble(0xa000000000000001), 0.625); - EXPECT_EQ(ToDouble(0xb000000000000001), 0.6875); - EXPECT_EQ(ToDouble(0xc000000000000001), 0.75); - EXPECT_EQ(ToDouble(0xd000000000000001), 0.8125); - EXPECT_EQ(ToDouble(0xe000000000000001), 0.875); - EXPECT_EQ(ToDouble(0xf000000000000001), 0.9375); - - // Large powers of 2. - int64_t two_to_53 = int64_t{1} << 53; - EXPECT_EQ(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53), - two_to_53 - 1); - EXPECT_NE(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53 * 2), - two_to_53 * 2 - 1); - - // For values where every bit counts, the values scale as multiples of the - // input. - for (int i = 0; i < 100; ++i) { - EXPECT_EQ(i * ToDouble(0x0000000000000001), ToDouble(i)); - } - - // For each i: value generated from (1 << i). - double exp_values[64]; - exp_values[63] = 0.5; - for (int i = 62; i >= 0; --i) exp_values[i] = 0.5 * exp_values[i + 1]; - constexpr uint64_t one = 1; - for (int i = 0; i < 64; ++i) { - EXPECT_EQ(ToDouble(one << i), exp_values[i]); - for (int j = 1; j < DBL_MANT_DIG && i - j >= 0; ++j) { - EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToDouble((one << i) + (one << (i - j))), - exp_values[i] + exp_values[i - j]); - } - for (int j = DBL_MANT_DIG; i - j >= 0; ++j) { - EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]); - EXPECT_EQ(ToDouble((one << i) + (one << (i - j))), exp_values[i]); - } - } -} - -TEST(DistributionImplTest, U64ToDoubleSignedTest) { - auto ToDouble = [](uint64_t a) { - return RandU64ToDouble(a); - }; - - EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); - - EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20); - EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); - - const double e_plus = ToDouble(0x0000000000000001); - const double e_minus = ToDouble(0x8000000000000001); - EXPECT_EQ(e_plus, 1.084202172485504434e-19); - EXPECT_EQ(e_minus, -1.084202172485504434e-19); - - EXPECT_EQ(ToDouble(0x3fffffffffffffef), 0.499999999999999944489); - EXPECT_EQ(ToDouble(0xbfffffffffffffef), -0.499999999999999944489); - - // For values > 0.5, RandU64ToDouble discards up to 10 bits. (63-53). - EXPECT_EQ(ToDouble(0x4000000000000000), 0.5); - EXPECT_EQ(ToDouble(0x4000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x40000000000003FF), 0.5); - - EXPECT_EQ(ToDouble(0xC000000000000000), -0.5); - EXPECT_EQ(ToDouble(0xC000000000000001), -0.5); - EXPECT_EQ(ToDouble(0xC0000000000003FF), -0.5); - - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFe), 0.999999999999999888978); - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999999999888978); - - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF)); - - EXPECT_LT(ToDouble(0x7FFFFFFFFFFFFFFF), 1.0); - EXPECT_GT(ToDouble(0x7FFFFFFFFFFFFFFF), 0.9999999999); - - EXPECT_GT(ToDouble(0xFFFFFFFFFFFFFFFe), -1.0); - EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999); - - EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFFC00)); - EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00)); - EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFF3FF)); - EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFF3FF)); - - EXPECT_EQ(ToDouble(0x1000000000000001), 0.125); - EXPECT_EQ(ToDouble(0x2000000000000001), 0.25); - EXPECT_EQ(ToDouble(0x3000000000000001), 0.375); - EXPECT_EQ(ToDouble(0x4000000000000001), 0.5); - EXPECT_EQ(ToDouble(0x5000000000000001), 0.625); - EXPECT_EQ(ToDouble(0x6000000000000001), 0.75); - EXPECT_EQ(ToDouble(0x7000000000000001), 0.875); - EXPECT_EQ(ToDouble(0x7800000000000001), 0.9375); - EXPECT_EQ(ToDouble(0x7c00000000000001), 0.96875); - EXPECT_EQ(ToDouble(0x7e00000000000001), 0.984375); - EXPECT_EQ(ToDouble(0x7f00000000000001), 0.9921875); - - // 0x8000000000000000 ~= 0 - EXPECT_EQ(ToDouble(0x9000000000000001), -0.125); - EXPECT_EQ(ToDouble(0xa000000000000001), -0.25); - EXPECT_EQ(ToDouble(0xb000000000000001), -0.375); - EXPECT_EQ(ToDouble(0xc000000000000001), -0.5); - EXPECT_EQ(ToDouble(0xd000000000000001), -0.625); - EXPECT_EQ(ToDouble(0xe000000000000001), -0.75); - EXPECT_EQ(ToDouble(0xf000000000000001), -0.875); - - // Large powers of 2. - int64_t two_to_53 = int64_t{1} << 53; - EXPECT_EQ(static_cast(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53), - two_to_53 - 1); - EXPECT_EQ(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53), - -(two_to_53 - 1)); - - EXPECT_NE(static_cast(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53 * 2), - two_to_53 * 2 - 1); - - // For values where every bit counts, the values scale as multiples of the - // input. - for (int i = 1; i < 100; ++i) { - EXPECT_EQ(i * e_plus, ToDouble(i)) << i; - EXPECT_EQ(i * e_minus, ToDouble(0x8000000000000000 | i)) << i; - } -} - -TEST(DistributionImplTest, ExhaustiveFloat) { - using absl::base_internal::CountLeadingZeros64; - auto ToFloat = [](uint64_t a) { - return RandU64ToFloat(a); - }; - - // Rely on RandU64ToFloat generating values from greatest to least when - // supplied with uint64_t values from greatest (0xfff...) to least (0x0). Thus, - // this algorithm stores the previous value, and if the new value is at - // greater than or equal to the previous value, then there is a collision in - // the generation algorithm. - // - // Use the computation below to convert the random value into a result: - // double res = a() * (1.0f - sample) + b() * sample; - float last_f = 1.0, last_g = 2.0; - uint64_t f_collisions = 0, g_collisions = 0; - uint64_t f_unique = 0, g_unique = 0; - uint64_t total = 0; - auto count = [&](const float r) { - total++; - // `f` is mapped to the range [0, 1) (default) - const float f = 0.0f * (1.0f - r) + 1.0f * r; - if (f >= last_f) { - f_collisions++; - } else { - f_unique++; - last_f = f; - } - // `g` is mapped to the range [1, 2) - const float g = 1.0f * (1.0f - r) + 2.0f * r; - if (g >= last_g) { - g_collisions++; - } else { - g_unique++; - last_g = g; - } - }; - - size_t limit = absl::GetFlag(FLAGS_absl_random_test_trials); - - // Generate all uint64_t which have unique floating point values. - // Counting down from 0xFFFFFFFFFFFFFFFFu ... 0x0u - uint64_t x = ~uint64_t(0); - for (; x != 0 && limit > 0;) { - constexpr int kDig = (64 - FLT_MANT_DIG); - // Set a decrement value & the next point at which to change - // the decrement value. By default these are 1, 0. - uint64_t dec = 1; - uint64_t chk = 0; - - // Adjust decrement and check value based on how many leading 0 - // bits are set in the current value. - const int clz = CountLeadingZeros64(x); - if (clz < kDig) { - dec <<= (kDig - clz); - chk = (~uint64_t(0)) >> (clz + 1); - } - for (; x > chk && limit > 0; x -= dec) { - count(ToFloat(x)); - --limit; - } - } - - static_assert(FLT_MANT_DIG == 24, - "The float type is expected to have a 24 bit mantissa."); - - if (limit != 0) { - // There are between 2^28 and 2^29 unique values in the range [0, 1). For - // the low values of x, there are 2^24 -1 unique values. Once x > 2^24, - // there are 40 * 2^24 unique values. Thus: - // (2 + 4 + 8 ... + 2^23) + 40 * 2^23 - EXPECT_LT(1 << 28, f_unique); - EXPECT_EQ((1 << 24) + 40 * (1 << 23) - 1, f_unique); - EXPECT_EQ(total, f_unique); - EXPECT_EQ(0, f_collisions); - - // Expect at least 2^23 unique values for the range [1, 2) - EXPECT_LE(1 << 23, g_unique); - EXPECT_EQ(total - g_unique, g_collisions); - } -} - -} // namespace diff --git a/absl/random/internal/generate_real.h b/absl/random/internal/generate_real.h new file mode 100644 index 00000000..246d863e --- /dev/null +++ b/absl/random/internal/generate_real.h @@ -0,0 +1,144 @@ +// Copyright 2017 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. + +#ifndef ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_ +#define ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_ + +// This file contains some implementation details which are used by one or more +// of the absl random number distributions. + +#include +#include +#include +#include + +#include "absl/base/internal/bits.h" +#include "absl/meta/type_traits.h" +#include "absl/random/internal/fastmath.h" +#include "absl/random/internal/traits.h" + +namespace absl { +namespace random_internal { + +// Tristate tag types controlling the output of GenerateRealFromBits. +struct GeneratePositiveTag {}; +struct GenerateNegativeTag {}; +struct GenerateSignedTag {}; + +// GenerateRealFromBits generates a single real value from a single 64-bit +// `bits` with template fields controlling the output. +// +// The `SignedTag` parameter controls whether positive, negative, +// or either signed/unsigned may be returned. +// When SignedTag == GeneratePositiveTag, range is U(0, 1) +// When SignedTag == GenerateNegativeTag, range is U(-1, 0) +// When SignedTag == GenerateSignedTag, range is U(-1, 1) +// +// When the `IncludeZero` parameter is true, the function may return 0 for some +// inputs, otherwise it never returns 0. +// +// When a value in U(0,1) is required, use: +// Uniform64ToReal; +// +// When a value in U(-1,1) is required, use: +// Uniform64ToReal; +// +// This generates more distinct values than the mathematical equivalent +// `U(0, 1) * 2.0 - 1.0`. +// +// Scaling the result by powers of 2 (and avoiding a multiply) is also possible: +// GenerateRealFromBits(..., -1); => U(0, 0.5) +// GenerateRealFromBits(..., 1); => U(0, 2) +// +template +inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) { + using real_type = RealType; + using uint_type = absl::conditional_t::value, + uint32_t, uint64_t>; + + static_assert( + (std::is_same::value || + std::is_same::value), + "GenerateRealFromBits must be parameterized by either float or double."); + + static_assert(sizeof(uint_type) == sizeof(real_type), + "Mismatched unsinged and real types."); + + static_assert((std::numeric_limits::is_iec559 && + std::numeric_limits::radix == 2), + "RealType representation is not IEEE 754 binary."); + + static_assert((std::is_same::value || + std::is_same::value || + std::is_same::value), + ""); + + static constexpr int kExp = std::numeric_limits::digits - 1; + static constexpr uint_type kMask = (static_cast(1) << kExp) - 1u; + static constexpr int kUintBits = sizeof(uint_type) * 8; + + int exp = exp_bias + int{std::numeric_limits::max_exponent - 2}; + + // Determine the sign bit. + // Depending on the SignedTag, this may use the left-most bit + // or it may be a constant value. + uint_type sign = std::is_same::value + ? (static_cast(1) << (kUintBits - 1)) + : 0; + if (std::is_same::value) { + if (std::is_same::value) { + sign = bits & uint64_t{0x8000000000000000}; + } + if (std::is_same::value) { + const uint64_t tmp = bits & uint64_t{0x8000000000000000}; + sign = static_cast(tmp >> 32); + } + // adjust the bits and the exponent to account for removing + // the leading bit. + bits = bits & uint64_t{0x7FFFFFFFFFFFFFFF}; + exp++; + } + if (IncludeZero) { + if (bits == 0u) return 0; + } + + // Number of leading zeros is mapped to the exponent: 2^-clz + // bits is 0..01xxxxxx. After shifting, we're left with 1xxx...0..0 + int clz = base_internal::CountLeadingZeros64(bits); + bits <<= (IncludeZero ? clz : (clz & 63)); // remove 0-bits. + exp -= clz; // set the exponent. + bits >>= (63 - kExp); + + // Construct the 32-bit or 64-bit IEEE 754 floating-point value from + // the individual fields: sign, exp, mantissa(bits). + uint_type val = + (std::is_same::value ? 0u : sign) | + (static_cast(exp) << kExp) | + (static_cast(bits) & kMask); + + // bit_cast to the output-type + real_type result; + memcpy(static_cast(&result), static_cast(&val), + sizeof(result)); + return result; +} + +} // namespace random_internal +} // namespace absl + +#endif // ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_ diff --git a/absl/random/internal/generate_real_test.cc b/absl/random/internal/generate_real_test.cc new file mode 100644 index 00000000..aa02f0c2 --- /dev/null +++ b/absl/random/internal/generate_real_test.cc @@ -0,0 +1,497 @@ +// Copyright 2017 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. + +#include "absl/random/internal/generate_real.h" + +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/base/internal/bits.h" +#include "absl/flags/flag.h" + +ABSL_FLAG(int64_t, absl_random_test_trials, 50000, + "Number of trials for the probability tests."); + +using absl::random_internal::GenerateNegativeTag; +using absl::random_internal::GeneratePositiveTag; +using absl::random_internal::GenerateRealFromBits; +using absl::random_internal::GenerateSignedTag; + +namespace { + +TEST(GenerateRealTest, U64ToFloat_Positive_NoZero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 2.710505431e-20f); + EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f); + EXPECT_EQ(ToFloat(0x8000000000000000), 0.5); + EXPECT_EQ(ToFloat(0x8000000000000001), 0.5); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Positive_Zero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 0.0); + EXPECT_EQ(ToFloat(0x0000000000000001), 5.421010862e-20f); + EXPECT_EQ(ToFloat(0x8000000000000000), 0.5); + EXPECT_EQ(ToFloat(0x8000000000000001), 0.5); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Negative_NoZero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), -2.710505431e-20f); + EXPECT_EQ(ToFloat(0x0000000000000001), -5.421010862e-20f); + EXPECT_EQ(ToFloat(0x8000000000000000), -0.5); + EXPECT_EQ(ToFloat(0x8000000000000001), -0.5); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Negative_Zero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 0.0); + EXPECT_EQ(ToFloat(0x0000000000000001), -5.421010862e-20f); + EXPECT_EQ(ToFloat(0x8000000000000000), -0.5); + EXPECT_EQ(ToFloat(0x8000000000000001), -0.5); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Signed_NoZero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 5.421010862e-20f); + EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f); + EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f); + EXPECT_EQ(ToFloat(0x8000000000000000), -5.421010862e-20f); + EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Signed_Zero_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 0); + EXPECT_EQ(ToFloat(0x0000000000000001), 1.084202172e-19f); + EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 0.9999999404f); + EXPECT_EQ(ToFloat(0x8000000000000000), 0); + EXPECT_EQ(ToFloat(0x8000000000000001), -1.084202172e-19f); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), -0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloat_Signed_Bias_Test) { + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a, 1); + }; + EXPECT_EQ(ToFloat(0x0000000000000000), 0); + EXPECT_EQ(ToFloat(0x0000000000000001), 2 * 1.084202172e-19f); + EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), 2 * 0.9999999404f); + EXPECT_EQ(ToFloat(0x8000000000000000), 0); + EXPECT_EQ(ToFloat(0x8000000000000001), 2 * -1.084202172e-19f); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 2 * -0.9999999404f); +} + +TEST(GenerateRealTest, U64ToFloatTest) { + auto ToFloat = [](uint64_t a) -> float { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToFloat(0x0000000000000000), 0.0f); + + EXPECT_EQ(ToFloat(0x8000000000000000), 0.5f); + EXPECT_EQ(ToFloat(0x8000000000000001), 0.5f); + EXPECT_EQ(ToFloat(0x800000FFFFFFFFFF), 0.5f); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), 0.9999999404f); + + EXPECT_GT(ToFloat(0x0000000000000001), 0.0f); + + EXPECT_NE(ToFloat(0x7FFFFF0000000000), ToFloat(0x7FFFFEFFFFFFFFFF)); + + EXPECT_LT(ToFloat(0xFFFFFFFFFFFFFFFF), 1.0f); + int32_t two_to_24 = 1 << 24; + EXPECT_EQ(static_cast(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24), + two_to_24 - 1); + EXPECT_NE(static_cast(ToFloat(0xFFFFFFFFFFFFFFFF) * two_to_24 * 2), + two_to_24 * 2 - 1); + EXPECT_EQ(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFF0000000000)); + EXPECT_NE(ToFloat(0xFFFFFFFFFFFFFFFF), ToFloat(0xFFFFFEFFFFFFFFFF)); + EXPECT_EQ(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF8000000000)); + EXPECT_NE(ToFloat(0x7FFFFFFFFFFFFFFF), ToFloat(0x7FFFFF7FFFFFFFFF)); + EXPECT_EQ(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFC000000000)); + EXPECT_NE(ToFloat(0x3FFFFFFFFFFFFFFF), ToFloat(0x3FFFFFBFFFFFFFFF)); + + // For values where every bit counts, the values scale as multiples of the + // input. + for (int i = 0; i < 100; ++i) { + EXPECT_EQ(i * ToFloat(0x0000000000000001), ToFloat(i)); + } + + // For each i: value generated from (1 << i). + float exp_values[64]; + exp_values[63] = 0.5f; + for (int i = 62; i >= 0; --i) exp_values[i] = 0.5f * exp_values[i + 1]; + constexpr uint64_t one = 1; + for (int i = 0; i < 64; ++i) { + EXPECT_EQ(ToFloat(one << i), exp_values[i]); + for (int j = 1; j < FLT_MANT_DIG && i - j >= 0; ++j) { + EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]); + EXPECT_EQ(ToFloat((one << i) + (one << (i - j))), + exp_values[i] + exp_values[i - j]); + } + for (int j = FLT_MANT_DIG; i - j >= 0; ++j) { + EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]); + EXPECT_EQ(ToFloat((one << i) + (one << (i - j))), exp_values[i]); + } + } +} + +TEST(GenerateRealTest, U64ToDouble_Positive_NoZero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 2.710505431213761085e-20); + EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x0000000000000002), 1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); + EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_Positive_Zero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); + EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); + EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_Negative_NoZero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), -2.710505431213761085e-20); + EXPECT_EQ(ToDouble(0x0000000000000001), -5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x0000000000000002), -1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0x8000000000000000), -0.5); + EXPECT_EQ(ToDouble(0x8000000000000001), -0.5); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_Negative_Zero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); + EXPECT_EQ(ToDouble(0x0000000000000001), -5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x0000000000000002), -1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0x8000000000000000), -0.5); + EXPECT_EQ(ToDouble(0x8000000000000001), -0.5); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_Signed_NoZero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978); + EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_Signed_Zero_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + EXPECT_EQ(ToDouble(0x0000000000000000), 0); + EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978); + EXPECT_EQ(ToDouble(0x8000000000000000), 0); + EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978); +} + +TEST(GenerateRealTest, U64ToDouble_GenerateSignedTag_Bias_Test) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a, -1); + }; + EXPECT_EQ(ToDouble(0x0000000000000000), 0); + EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19 / 2); + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), 0.999999999999999888978 / 2); + EXPECT_EQ(ToDouble(0x8000000000000000), 0); + EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19 / 2); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), -0.999999999999999888978 / 2); +} + +TEST(GenerateRealTest, U64ToDoubleTest) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); + EXPECT_EQ(ToDouble(0x0000000000000000), 0.0); + + EXPECT_EQ(ToDouble(0x0000000000000001), 5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x7fffffffffffffef), 0.499999999999999944489); + EXPECT_EQ(ToDouble(0x8000000000000000), 0.5); + + // For values > 0.5, RandU64ToDouble discards up to 11 bits. (64-53). + EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); + EXPECT_EQ(ToDouble(0x80000000000007FF), 0.5); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), 0.999999999999999888978); + EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF)); + + EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFF), 1.0); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF800)); + EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFF), ToDouble(0xFFFFFFFFFFFFF7FF)); + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00)); + EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFBFF)); + EXPECT_EQ(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFE00)); + EXPECT_NE(ToDouble(0x3FFFFFFFFFFFFFFF), ToDouble(0x3FFFFFFFFFFFFDFF)); + + EXPECT_EQ(ToDouble(0x1000000000000001), 0.0625); + EXPECT_EQ(ToDouble(0x2000000000000001), 0.125); + EXPECT_EQ(ToDouble(0x3000000000000001), 0.1875); + EXPECT_EQ(ToDouble(0x4000000000000001), 0.25); + EXPECT_EQ(ToDouble(0x5000000000000001), 0.3125); + EXPECT_EQ(ToDouble(0x6000000000000001), 0.375); + EXPECT_EQ(ToDouble(0x7000000000000001), 0.4375); + EXPECT_EQ(ToDouble(0x8000000000000001), 0.5); + EXPECT_EQ(ToDouble(0x9000000000000001), 0.5625); + EXPECT_EQ(ToDouble(0xa000000000000001), 0.625); + EXPECT_EQ(ToDouble(0xb000000000000001), 0.6875); + EXPECT_EQ(ToDouble(0xc000000000000001), 0.75); + EXPECT_EQ(ToDouble(0xd000000000000001), 0.8125); + EXPECT_EQ(ToDouble(0xe000000000000001), 0.875); + EXPECT_EQ(ToDouble(0xf000000000000001), 0.9375); + + // Large powers of 2. + int64_t two_to_53 = int64_t{1} << 53; + EXPECT_EQ(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53), + two_to_53 - 1); + EXPECT_NE(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53 * 2), + two_to_53 * 2 - 1); + + // For values where every bit counts, the values scale as multiples of the + // input. + for (int i = 0; i < 100; ++i) { + EXPECT_EQ(i * ToDouble(0x0000000000000001), ToDouble(i)); + } + + // For each i: value generated from (1 << i). + double exp_values[64]; + exp_values[63] = 0.5; + for (int i = 62; i >= 0; --i) exp_values[i] = 0.5 * exp_values[i + 1]; + constexpr uint64_t one = 1; + for (int i = 0; i < 64; ++i) { + EXPECT_EQ(ToDouble(one << i), exp_values[i]); + for (int j = 1; j < DBL_MANT_DIG && i - j >= 0; ++j) { + EXPECT_NE(exp_values[i] + exp_values[i - j], exp_values[i]); + EXPECT_EQ(ToDouble((one << i) + (one << (i - j))), + exp_values[i] + exp_values[i - j]); + } + for (int j = DBL_MANT_DIG; i - j >= 0; ++j) { + EXPECT_EQ(exp_values[i] + exp_values[i - j], exp_values[i]); + EXPECT_EQ(ToDouble((one << i) + (one << (i - j))), exp_values[i]); + } + } +} + +TEST(GenerateRealTest, U64ToDoubleSignedTest) { + auto ToDouble = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + EXPECT_EQ(ToDouble(0x0000000000000000), 5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x0000000000000001), 1.084202172485504434e-19); + + EXPECT_EQ(ToDouble(0x8000000000000000), -5.42101086242752217004e-20); + EXPECT_EQ(ToDouble(0x8000000000000001), -1.084202172485504434e-19); + + const double e_plus = ToDouble(0x0000000000000001); + const double e_minus = ToDouble(0x8000000000000001); + EXPECT_EQ(e_plus, 1.084202172485504434e-19); + EXPECT_EQ(e_minus, -1.084202172485504434e-19); + + EXPECT_EQ(ToDouble(0x3fffffffffffffef), 0.499999999999999944489); + EXPECT_EQ(ToDouble(0xbfffffffffffffef), -0.499999999999999944489); + + // For values > 0.5, RandU64ToDouble discards up to 10 bits. (63-53). + EXPECT_EQ(ToDouble(0x4000000000000000), 0.5); + EXPECT_EQ(ToDouble(0x4000000000000001), 0.5); + EXPECT_EQ(ToDouble(0x40000000000003FF), 0.5); + + EXPECT_EQ(ToDouble(0xC000000000000000), -0.5); + EXPECT_EQ(ToDouble(0xC000000000000001), -0.5); + EXPECT_EQ(ToDouble(0xC0000000000003FF), -0.5); + + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFe), 0.999999999999999888978); + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999999999888978); + + EXPECT_NE(ToDouble(0x7FFFFFFFFFFFF800), ToDouble(0x7FFFFFFFFFFFF7FF)); + + EXPECT_LT(ToDouble(0x7FFFFFFFFFFFFFFF), 1.0); + EXPECT_GT(ToDouble(0x7FFFFFFFFFFFFFFF), 0.9999999999); + + EXPECT_GT(ToDouble(0xFFFFFFFFFFFFFFFe), -1.0); + EXPECT_LT(ToDouble(0xFFFFFFFFFFFFFFFe), -0.999999999); + + EXPECT_EQ(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFFC00)); + EXPECT_EQ(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFFC00)); + EXPECT_NE(ToDouble(0xFFFFFFFFFFFFFFFe), ToDouble(0xFFFFFFFFFFFFF3FF)); + EXPECT_NE(ToDouble(0x7FFFFFFFFFFFFFFF), ToDouble(0x7FFFFFFFFFFFF3FF)); + + EXPECT_EQ(ToDouble(0x1000000000000001), 0.125); + EXPECT_EQ(ToDouble(0x2000000000000001), 0.25); + EXPECT_EQ(ToDouble(0x3000000000000001), 0.375); + EXPECT_EQ(ToDouble(0x4000000000000001), 0.5); + EXPECT_EQ(ToDouble(0x5000000000000001), 0.625); + EXPECT_EQ(ToDouble(0x6000000000000001), 0.75); + EXPECT_EQ(ToDouble(0x7000000000000001), 0.875); + EXPECT_EQ(ToDouble(0x7800000000000001), 0.9375); + EXPECT_EQ(ToDouble(0x7c00000000000001), 0.96875); + EXPECT_EQ(ToDouble(0x7e00000000000001), 0.984375); + EXPECT_EQ(ToDouble(0x7f00000000000001), 0.9921875); + + // 0x8000000000000000 ~= 0 + EXPECT_EQ(ToDouble(0x9000000000000001), -0.125); + EXPECT_EQ(ToDouble(0xa000000000000001), -0.25); + EXPECT_EQ(ToDouble(0xb000000000000001), -0.375); + EXPECT_EQ(ToDouble(0xc000000000000001), -0.5); + EXPECT_EQ(ToDouble(0xd000000000000001), -0.625); + EXPECT_EQ(ToDouble(0xe000000000000001), -0.75); + EXPECT_EQ(ToDouble(0xf000000000000001), -0.875); + + // Large powers of 2. + int64_t two_to_53 = int64_t{1} << 53; + EXPECT_EQ(static_cast(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53), + two_to_53 - 1); + EXPECT_EQ(static_cast(ToDouble(0xFFFFFFFFFFFFFFFF) * two_to_53), + -(two_to_53 - 1)); + + EXPECT_NE(static_cast(ToDouble(0x7FFFFFFFFFFFFFFF) * two_to_53 * 2), + two_to_53 * 2 - 1); + + // For values where every bit counts, the values scale as multiples of the + // input. + for (int i = 1; i < 100; ++i) { + EXPECT_EQ(i * e_plus, ToDouble(i)) << i; + EXPECT_EQ(i * e_minus, ToDouble(0x8000000000000000 | i)) << i; + } +} + +TEST(GenerateRealTest, ExhaustiveFloat) { + using absl::base_internal::CountLeadingZeros64; + auto ToFloat = [](uint64_t a) { + return GenerateRealFromBits(a); + }; + + // Rely on RandU64ToFloat generating values from greatest to least when + // supplied with uint64_t values from greatest (0xfff...) to least (0x0). Thus, + // this algorithm stores the previous value, and if the new value is at + // greater than or equal to the previous value, then there is a collision in + // the generation algorithm. + // + // Use the computation below to convert the random value into a result: + // double res = a() * (1.0f - sample) + b() * sample; + float last_f = 1.0, last_g = 2.0; + uint64_t f_collisions = 0, g_collisions = 0; + uint64_t f_unique = 0, g_unique = 0; + uint64_t total = 0; + auto count = [&](const float r) { + total++; + // `f` is mapped to the range [0, 1) (default) + const float f = 0.0f * (1.0f - r) + 1.0f * r; + if (f >= last_f) { + f_collisions++; + } else { + f_unique++; + last_f = f; + } + // `g` is mapped to the range [1, 2) + const float g = 1.0f * (1.0f - r) + 2.0f * r; + if (g >= last_g) { + g_collisions++; + } else { + g_unique++; + last_g = g; + } + }; + + size_t limit = absl::GetFlag(FLAGS_absl_random_test_trials); + + // Generate all uint64_t which have unique floating point values. + // Counting down from 0xFFFFFFFFFFFFFFFFu ... 0x0u + uint64_t x = ~uint64_t(0); + for (; x != 0 && limit > 0;) { + constexpr int kDig = (64 - FLT_MANT_DIG); + // Set a decrement value & the next point at which to change + // the decrement value. By default these are 1, 0. + uint64_t dec = 1; + uint64_t chk = 0; + + // Adjust decrement and check value based on how many leading 0 + // bits are set in the current value. + const int clz = CountLeadingZeros64(x); + if (clz < kDig) { + dec <<= (kDig - clz); + chk = (~uint64_t(0)) >> (clz + 1); + } + for (; x > chk && limit > 0; x -= dec) { + count(ToFloat(x)); + --limit; + } + } + + static_assert(FLT_MANT_DIG == 24, + "The float type is expected to have a 24 bit mantissa."); + + if (limit != 0) { + // There are between 2^28 and 2^29 unique values in the range [0, 1). For + // the low values of x, there are 2^24 -1 unique values. Once x > 2^24, + // there are 40 * 2^24 unique values. Thus: + // (2 + 4 + 8 ... + 2^23) + 40 * 2^23 + EXPECT_LT(1 << 28, f_unique); + EXPECT_EQ((1 << 24) + 40 * (1 << 23) - 1, f_unique); + EXPECT_EQ(total, f_unique); + EXPECT_EQ(0, f_collisions); + + // Expect at least 2^23 unique values for the range [1, 2) + EXPECT_LE(1 << 23, g_unique); + EXPECT_EQ(total - g_unique, g_collisions); + } +} + +} // namespace diff --git a/absl/random/log_uniform_int_distribution.h b/absl/random/log_uniform_int_distribution.h index ac43416e..956a6907 100644 --- a/absl/random/log_uniform_int_distribution.h +++ b/absl/random/log_uniform_int_distribution.h @@ -23,8 +23,8 @@ #include #include -#include "absl/random/internal/distribution_impl.h" #include "absl/random/internal/fastmath.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" #include "absl/random/internal/traits.h" #include "absl/random/uniform_int_distribution.h" diff --git a/absl/random/poisson_distribution.h b/absl/random/poisson_distribution.h index 7750b1c9..23a953ff 100644 --- a/absl/random/poisson_distribution.h +++ b/absl/random/poisson_distribution.h @@ -22,9 +22,9 @@ #include #include -#include "absl/random/internal/distribution_impl.h" #include "absl/random/internal/fast_uniform_bits.h" #include "absl/random/internal/fastmath.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" namespace absl { @@ -164,9 +164,9 @@ typename poisson_distribution::result_type poisson_distribution::operator()( URBG& g, // NOLINT(runtime/references) const param_type& p) { - using random_internal::PositiveValueT; - using random_internal::RandU64ToDouble; - using random_internal::SignedValueT; + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + using random_internal::GenerateSignedTag; if (p.split_ != 0) { // Use Knuth's algorithm with range splitting to avoid floating-point @@ -186,7 +186,8 @@ poisson_distribution::operator()( for (int split = p.split_; split > 0; --split) { double r = 1.0; do { - r *= RandU64ToDouble(fast_u64_(g)); + r *= GenerateRealFromBits( + fast_u64_(g)); // U(-1, 0) ++n; } while (r > p.emu_); --n; @@ -205,10 +206,11 @@ poisson_distribution::operator()( // and k = max(f). const double a = p.mean_ + 0.5; for (;;) { - const double u = - RandU64ToDouble(fast_u64_(g)); // (0, 1) - const double v = - RandU64ToDouble(fast_u64_(g)); // (-1, 1) + const double u = GenerateRealFromBits( + fast_u64_(g)); // U(0, 1) + const double v = GenerateRealFromBits( + fast_u64_(g)); // U(-1, 1) + const double x = std::floor(p.s_ * v / u + a); if (x < 0) continue; // f(negative) = 0 const double rhs = x * p.lmu_; diff --git a/absl/random/uniform_int_distribution.h b/absl/random/uniform_int_distribution.h index 02aa3765..dc8ba8c1 100644 --- a/absl/random/uniform_int_distribution.h +++ b/absl/random/uniform_int_distribution.h @@ -34,7 +34,6 @@ #include #include "absl/base/optimization.h" -#include "absl/random/internal/distribution_impl.h" #include "absl/random/internal/fast_uniform_bits.h" #include "absl/random/internal/iostream_state_saver.h" #include "absl/random/internal/traits.h" diff --git a/absl/random/uniform_real_distribution.h b/absl/random/uniform_real_distribution.h index 336abb39..bf2ed2c5 100644 --- a/absl/random/uniform_real_distribution.h +++ b/absl/random/uniform_real_distribution.h @@ -39,8 +39,9 @@ #include #include -#include "absl/random/internal/distribution_impl.h" +#include "absl/meta/type_traits.h" #include "absl/random/internal/fast_uniform_bits.h" +#include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" namespace absl { @@ -76,6 +77,7 @@ class uniform_real_distribution { // is not possible, so value generation cannot use the full range of the // real type. assert(range_ <= (std::numeric_limits::max)()); + assert(std::isfinite(range_)); } result_type a() const { return lo_; } @@ -151,10 +153,15 @@ template typename uniform_real_distribution::result_type uniform_real_distribution::operator()( URBG& gen, const param_type& p) { // NOLINT(runtime/references) - using random_internal::PositiveValueT; + using random_internal::GeneratePositiveTag; + using random_internal::GenerateRealFromBits; + using real_type = + absl::conditional_t::value, float, double>; + while (true) { - const result_type sample = random_internal::RandU64ToReal< - result_type>::template Value(fast_u64_(gen)); + const result_type sample = + GenerateRealFromBits( + fast_u64_(gen)); const result_type res = p.a() + (sample * p.range_); if (res < p.b() || p.range_ <= 0 || !std::isfinite(p.range_)) { return res; -- cgit v1.2.3 From 8207907f4f7fbaeeaa2b7340c76875e06fd345ba Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 30 Oct 2019 08:00:44 -0700 Subject: Export of internal Abseil changes -- 2f49cb9009386bc67bf54a2908c8720b749c8b7f by Greg Falcon : docs: fix typo Import of https://github.com/abseil/abseil-cpp/pull/397 PiperOrigin-RevId: 277504420 -- f2bed362c1c12d3fa9c22d11f2b918668e8c37b7 by Abseil Team : Avoid our is_[copy/move]_assignable workarounds in MSVC 19.20 and on, since that release introduces a regression that breaks our workaround. We should ideally use the std forms in more cases, but branching when our workarounds fail is simpler to maintain. PiperOrigin-RevId: 277502334 -- e33de894ffd49848b9e088f59acc9743d1661948 by Derek Mauro : Update rules_cc version. The mirror.bazel.build URL does not exist (cache expiration?) PiperOrigin-RevId: 277498394 -- b23757b0747c64634d2d701433782c969effef19 by Abseil Team : Fix https://github.com/abseil/abseil-cpp/issues/394. PiperOrigin-RevId: 277491405 -- 54c75b8b29813531c52d67cf0ba7063baae4a4f3 by Abseil Team : Fix comment typos: waker => waiter. PiperOrigin-RevId: 277376952 -- 874eeaa3b3af808fc88b6355245f643674f5e36e by Abseil Team : Don't use atomic ops on waiter and wakeup counts in CONDVAR waiter mode. Just guard the waiter and wakeup counts with the mutex. This eliminates the race. Also fix a typo in the error message for pthread_cond_timedwait. PiperOrigin-RevId: 277366017 -- ce8c9a63109214519b5a7eaecef2c663c4d566df by Greg Falcon : Implement the config options for our four main C++ forward compatibility types. These options control whether the names `any`, `optional`, `string_view`, and `variant` in namespace `absl` are aliases to the corresponding C++17 types in namespace `std`. By default, we continue to auto-detect the configuration of the compiler being run. These options are not intended to be modified on the command line (as -D flags, say). Instead, the options.h file can be modified by distributors of Abseil (e.g., binary packagers, maintainers of local copies of Abseil, etc.) Changing options will change Abseil in an ODR sense. Any program must only link in a single version of Abseil. Linking libraries that use Abseil configured with different options is an error: there is no ABI compatibility guarantee when linking different configurations, even if the Abseil versions used are otherwise exactly identical. PiperOrigin-RevId: 277364298 -- 5ed3ad42ae43a05862070f92f9ffd07f5c1f2b81 by Chris Kennelly : Suppress -Wimplicit-int-float-conversion. On recent builds of Clang, this is an error/warning. PiperOrigin-RevId: 277346168 -- 9b9b0055243c705189bb27d912e6d45a7789cdee by Eric Fiselier : Allow building Abseil as a shared library with CMake. By default CMake's `add_library` creates the target as a static library. However, users can override the default using the builtin CMake option -DBUILD_SHARED_LIBS=ON. This changes Abseil's CMake to respect this configuration option by removing the explicit `STATIC` in our usages of `add_library`. PiperOrigin-RevId: 277337753 -- 63a8b7b8ede3a9d851916929d6b8537f4f2508ca by Abseil Team : Improve AlphaNum Hex performance by using absl::numbers_internal::FastHexToBufferZeroPad16. PiperOrigin-RevId: 277318108 -- dd047f7e92032682d94b27732df0e4d0670e24a4 by CJ Johnson : Internal change PiperOrigin-RevId: 277316913 -- d19ee7074929fed08973cc5b40a844573ce1e0a6 by Abseil Team : Handle invoking [[nodiscard]] functions correctly in our tests. PiperOrigin-RevId: 277301500 -- 5373f3737894ba9b8481e95e5f58c7957c00d26a by Chris Kennelly : For internal reasons, loosen visibility restrictions of `//absl/base:malloc_internal`. As an internal-namespace interface, this module remains unsupported. We reserve the right to change, delete, or re-restrict visibility to this target at any time. PiperOrigin-RevId: 277118689 -- 44e4f6655e05393a375d09b3625c192b1fde5909 by Abseil Team : Fix error in example civil day comment. PiperOrigin-RevId: 277103315 -- 7657392b4ce48469106f11cdb952a0bc76a28df3 by Abseil Team : Internal change PiperOrigin-RevId: 277056076 -- c75bda76f40b01fa249b75b5a70c1f5907e56c76 by Abseil Team : Suppress lifetime constant-initialization tests when building with MSVC versions > 19.0. These are broken due to non-compliant initialization order in these versions: https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html We don't know when Microsoft will fix this bug. PiperOrigin-RevId: 277049770 -- 16c3b9bf2a1796efa57f97b00bcd6227fbccca1f by Matt Calabrese : Avoid our is_[copy/move]_assignable workarounds in MSVC 19.20 and on, since that release introduces a regression that breaks our workaround. We should ideally use the std forms in more cases, but branching when our workarounds fail is simpler to maintain. PiperOrigin-RevId: 277048670 -- e91003fa3ee6026d9b80624a23fc144fa5d74810 by Chris Kennelly : Fix -Wimplicit-int-float-conversion warning in latest clang PiperOrigin-RevId: 276771618 -- 53087ca6603e86ad815f3dd9ab795cc0f79792c1 by Andy Soffer : Add documentation on absl::SNPrintF. PiperOrigin-RevId: 276694032 -- a9426af8cbd4c3a8f9053e7446c821852e41ff61 by Jorg Brown : Stop including kern/OSByteOrder.h in order to support __APPLE__ Apple compiles with clang now anyway, and clang has support for the built-in compiler swap functions that are much faster than any function call to the OS. PiperOrigin-RevId: 276625231 -- df974be5aa5b4dc1b09c356cb8816edfc7867e63 by Jorg Brown : Fix the build for Android x86-64 builds, where __SSE4_2__ is defined but _bswap64 is not. PiperOrigin-RevId: 276542642 -- d99dc092b3a5ad17643005e55f3b3cb6b9187ccc by Jorg Brown : Remove a byteswap from the non-SSE path of FastHexToBufferZeroPad16 Remove the need for including absl/base/internal/endian.h from the SSE case (since if we have the Intel SSE intrinsics, then clearly we also have the Intel Byte-Swap intrinsics.) PiperOrigin-RevId: 276532608 -- d67b106dc930d8558810ae3983613bb2ab1e0d36 by Abseil Team : Use explicit static_cast for int64_t to double conversion This uses an explicit static_cast() in the int64_t to double comparisons in duration.cc's SafeAddRepHi. This satisfies clang's -Wimplicit-int-to-float-conversion warning (with https://reviews.llvm.org/D64666). This may also make it easier for humans to realize that the comparison is happening between two floating point double precision values. It should have no impact on the behavior or generated code. Tested: No behavior change PiperOrigin-RevId: 276529211 GitOrigin-RevId: 2f49cb9009386bc67bf54a2908c8720b749c8b7f Change-Id: I71e0781893ce219960b8290d54b20532779cb0ff --- CMake/AbseilHelpers.cmake | 5 +- WORKSPACE | 8 +- absl/base/BUILD.bazel | 3 +- absl/base/CMakeLists.txt | 1 + absl/base/config.h | 63 +++++++++ absl/base/internal/endian.h | 8 -- absl/base/options.h | 188 +++++++++++++++++++++++++++ absl/container/flat_hash_map_test.cc | 4 +- absl/container/internal/inlined_vector.h | 29 ++--- absl/container/internal/raw_hash_set.h | 2 +- absl/meta/type_traits.h | 14 ++ absl/random/internal/nonsecure_base_test.cc | 7 +- absl/random/log_uniform_int_distribution.h | 16 ++- absl/strings/numbers.h | 13 +- absl/strings/str_cat.cc | 26 ++-- absl/strings/str_format.h | 6 + absl/strings/string_view.cc | 4 +- absl/strings/string_view.h | 6 +- absl/strings/string_view_test.cc | 12 +- absl/synchronization/internal/waiter.cc | 56 ++++---- absl/synchronization/internal/waiter.h | 7 +- absl/synchronization/lifetime_test.cc | 6 + absl/time/civil_time.h | 2 +- absl/time/duration.cc | 4 +- absl/time/time.h | 4 +- absl/types/any.h | 6 +- absl/types/any_exception_safety_test.cc | 4 +- absl/types/any_test.cc | 10 +- absl/types/bad_any_cast.cc | 4 +- absl/types/bad_any_cast.h | 6 +- absl/types/bad_optional_access.cc | 4 +- absl/types/bad_optional_access.h | 6 +- absl/types/bad_variant_access.cc | 4 +- absl/types/bad_variant_access.h | 6 +- absl/types/internal/variant.h | 4 +- absl/types/optional.h | 6 +- absl/types/optional_exception_safety_test.cc | 4 +- absl/types/optional_test.cc | 20 +-- absl/types/variant.h | 6 +- absl/types/variant_exception_safety_test.cc | 16 +-- absl/types/variant_test.cc | 34 ++--- absl/utility/utility.h | 14 +- 42 files changed, 459 insertions(+), 189 deletions(-) create mode 100644 absl/base/options.h (limited to 'absl/base/config.h') diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake index 67b97fe1..28fefaa6 100644 --- a/CMake/AbseilHelpers.cmake +++ b/CMake/AbseilHelpers.cmake @@ -104,7 +104,10 @@ function(absl_cc_library) endif() if(NOT ABSL_CC_LIB_IS_INTERFACE) - add_library(${_NAME} STATIC "") + # CMake creates static libraries by default. Users can specify + # -DBUILD_SHARED_LIBS=ON during initial configuration to build shared + # libraries instead. + add_library(${_NAME} "") target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS}) target_include_directories(${_NAME} PUBLIC diff --git a/WORKSPACE b/WORKSPACE index 572f5b1f..f2b10464 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -36,10 +36,10 @@ http_archive( # C++ rules for Bazel. http_archive( name = "rules_cc", - sha256 = "67412176974bfce3f4cf8bdaff39784a72ed709fc58def599d1f68710b58d68b", - strip_prefix = "rules_cc-b7fe9697c0c76ab2fd431a891dbb9a6a32ed7c3e", + sha256 = "9a446e9dd9c1bb180c86977a8dc1e9e659550ae732ae58bd2e8fd51e15b2c91d", + strip_prefix = "rules_cc-262ebec3c2296296526740db4aefce68c80de7fa", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_cc/archive/b7fe9697c0c76ab2fd431a891dbb9a6a32ed7c3e.zip", - "https://github.com/bazelbuild/rules_cc/archive/b7fe9697c0c76ab2fd431a891dbb9a6a32ed7c3e.zip", + "https://mirror.bazel.build/github.com/bazelbuild/rules_cc/archive/262ebec3c2296296526740db4aefce68c80de7fa.zip", + "https://github.com/bazelbuild/rules_cc/archive/262ebec3c2296296526740db4aefce68c80de7fa.zip", ], ) diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index ffeca630..6fc712d9 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -87,6 +87,7 @@ cc_library( name = "config", hdrs = [ "config.h", + "options.h", "policy_checks.h", ], copts = ABSL_DEFAULT_COPTS, @@ -137,7 +138,7 @@ cc_library( "//conditions:default": ["-pthread"], }) + ABSL_DEFAULT_LINKOPTS, visibility = [ - "//absl:__subpackages__", + "//visibility:public", ], deps = [ ":base", diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 2698213c..9550cdb2 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -75,6 +75,7 @@ absl_cc_library( config HDRS "config.h" + "options.h" "policy_checks.h" COPTS ${ABSL_DEFAULT_COPTS} diff --git a/absl/base/config.h b/absl/base/config.h index 24851fa3..46a84f1a 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -63,6 +63,7 @@ #include #endif +#include "absl/base/options.h" #include "absl/base/policy_checks.h" // ----------------------------------------------------------------------------- @@ -468,6 +469,68 @@ #define ABSL_HAVE_STD_STRING_VIEW 1 #endif +// ABSL_USES_STD_ANY +// +// Indicates whether absl::any is an alias for std::any. +#if !defined(ABSL_OPTION_USE_STD_ANY) +#error options.h is misconfigured. +#elif ABSL_OPTION_USE_STD_ANY == 0 || \ + (ABSL_OPTION_USE_STD_ANY == 2 && !defined(ABSL_HAVE_STD_ANY)) +#undef ABSL_USES_STD_ANY +#elif ABSL_OPTION_USE_STD_ANY == 1 || \ + (ABSL_OPTION_USE_STD_ANY == 2 && defined(ABSL_HAVE_STD_ANY)) +#define ABSL_USES_STD_ANY 1 +#else +#error options.h is misconfigured. +#endif + +// ABSL_USES_STD_OPTIONAL +// +// Indicates whether absl::optional is an alias for std::optional. +#if !defined(ABSL_OPTION_USE_STD_OPTIONAL) +#error options.h is misconfigured. +#elif ABSL_OPTION_USE_STD_OPTIONAL == 0 || \ + (ABSL_OPTION_USE_STD_OPTIONAL == 2 && !defined(ABSL_HAVE_STD_OPTIONAL)) +#undef ABSL_USES_STD_OPTIONAL +#elif ABSL_OPTION_USE_STD_OPTIONAL == 1 || \ + (ABSL_OPTION_USE_STD_OPTIONAL == 2 && defined(ABSL_HAVE_STD_OPTIONAL)) +#define ABSL_USES_STD_OPTIONAL 1 +#else +#error options.h is misconfigured. +#endif + +// ABSL_USES_STD_VARIANT +// +// Indicates whether absl::variant is an alias for std::variant. +#if !defined(ABSL_OPTION_USE_STD_VARIANT) +#error options.h is misconfigured. +#elif ABSL_OPTION_USE_STD_VARIANT == 0 || \ + (ABSL_OPTION_USE_STD_VARIANT == 2 && !defined(ABSL_HAVE_STD_VARIANT)) +#undef ABSL_USES_STD_VARIANT +#elif ABSL_OPTION_USE_STD_VARIANT == 1 || \ + (ABSL_OPTION_USE_STD_VARIANT == 2 && defined(ABSL_HAVE_STD_VARIANT)) +#define ABSL_USES_STD_VARIANT 1 +#else +#error options.h is misconfigured. +#endif + +// ABSL_USES_STD_STRING_VIEW +// +// Indicates whether absl::string_view is an alias for std::string_view. +#if !defined(ABSL_OPTION_USE_STD_STRING_VIEW) +#error options.h is misconfigured. +#elif ABSL_OPTION_USE_STD_STRING_VIEW == 0 || \ + (ABSL_OPTION_USE_STD_STRING_VIEW == 2 && \ + !defined(ABSL_HAVE_STD_STRING_VIEW)) +#undef ABSL_USES_STD_STRING_VIEW +#elif ABSL_OPTION_USE_STD_STRING_VIEW == 1 || \ + (ABSL_OPTION_USE_STD_STRING_VIEW == 2 && \ + defined(ABSL_HAVE_STD_STRING_VIEW)) +#define ABSL_USES_STD_STRING_VIEW 1 +#else +#error options.h is misconfigured. +#endif + // In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION // SEH exception from emplace for variant when constructing the // struct can throw. This defeats some of variant_test and diff --git a/absl/base/internal/endian.h b/absl/base/internal/endian.h index b43c9a46..8233cb52 100644 --- a/absl/base/internal/endian.h +++ b/absl/base/internal/endian.h @@ -19,9 +19,6 @@ // The following guarantees declaration of the byte swap functions #ifdef _MSC_VER #include // NOLINT(build/include) -#elif defined(__APPLE__) -// macOS / Darwin features -#include #elif defined(__FreeBSD__) #include #elif defined(__GLIBC__) @@ -63,11 +60,6 @@ inline uint16_t gbswap_16(uint16_t host_int) { return _byteswap_ushort(host_int); } -#elif defined(__APPLE__) -inline uint64_t gbswap_64(uint64_t host_int) { return OSSwapInt16(host_int); } -inline uint32_t gbswap_32(uint32_t host_int) { return OSSwapInt32(host_int); } -inline uint16_t gbswap_16(uint16_t host_int) { return OSSwapInt64(host_int); } - #else inline uint64_t gbswap_64(uint64_t host_int) { #if defined(__GNUC__) && defined(__x86_64__) && !defined(__APPLE__) diff --git a/absl/base/options.h b/absl/base/options.h new file mode 100644 index 00000000..3961e63f --- /dev/null +++ b/absl/base/options.h @@ -0,0 +1,188 @@ +#ifndef ABSL_BASE_OPTIONS_H_ +#define ABSL_BASE_OPTIONS_H_ + +// 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. +// +// ----------------------------------------------------------------------------- +// File: options.h +// ----------------------------------------------------------------------------- +// +// This file contains Abseil configuration options for setting specific +// implementations instead of letting Abseil determine which implementation to +// use at compile-time. Setting these options may be useful for package or build +// managers who wish to guarantee ABI stability within binary builds (which are +// otherwise difficult to enforce). +// +// *** IMPORTANT NOTICE FOR PACKAGE MANAGERS: It is important that +// maintainers of package managers who wish to package Abseil read and +// understand this file! *** +// +// Abseil contains a number of possible configuration endpoints, based on +// parameters such as the detected platform, language version, or command-line +// flags used to invoke the underlying binary. As is the case with all +// libraries, binaries which contain Abseil code must ensure that separate +// packages use the same compiled copy of Abseil to avoid a diamond dependency +// problem, which can occur if two packages built with different Abseil +// configuration settings are linked together. Diamond dependency problems in +// C++ may manifest as violations to the One Definition Rule (ODR) (resulting in +// linker errors), or undefined behavior (resulting in crashes). +// +// Diamond dependency problems can be avoided if all packages utilize the same +// exact version of Abseil. Building from source code with the same compilation +// parameters is the easiest way to avoid such dependency problems. However, for +// package managers who cannot control such compilation parameters, we are +// providing the file to allow you to inject ABI (Application Binary Interface) +// stability across builds. Settings options in this file will neither change +// API nor ABI, providing a stable copy of Abseil between packages. +// +// Care must be taken to keep options within these configurations isolated +// from any other dynamic settings, such as command-line flags which could alter +// these options. This file is provided specifically to help build and package +// managers provide a stable copy of Abseil within their libraries and binaries; +// other developers should not have need to alter the contents of this file. +// +// ----------------------------------------------------------------------------- +// Usage +// ----------------------------------------------------------------------------- +// +// For any particular package release, set the appropriate definitions within +// this file to whatever value makes the most sense for your package(s). Note +// that, by default, most of these options, at the moment, affect the +// implementation of types; future options may affect other implementation +// details. +// +// NOTE: the defaults within this file all assume that Abseil can select the +// proper Abseil implementation at compile-time, which will not be sufficient +// to guarantee ABI stability to package managers. +// +// ----------------------------------------------------------------------------- +// Type Compatibility Options +// ----------------------------------------------------------------------------- +// +// ABSL_OPTION_USE_STD_ANY +// +// This option controls whether absl::any is implemented as an alias to +// std::any, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::any. This requires that all code +// using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::any is available. This option is +// useful when you are building your entire program, including all of its +// dependencies, from source. It should not be used otherwise -- for example, +// if you are distributing Abseil in a binary package manager -- since in +// mode 2, absl::any will name a different type, with a different mangled name +// and binary layout, depending on the compiler flags passed by the end user. +// For more info, see https://abseil.io/about/design/dropin-types. +// +// User code should not inspect this macro. To check in the preprocessor if +// absl::any is a typedef of std::any, use the feature macro ABSL_USES_STD_ANY. + +#define ABSL_OPTION_USE_STD_ANY 2 + + +// ABSL_OPTION_USE_STD_OPTIONAL +// +// This option controls whether absl::optional is implemented as an alias to +// std::optional, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::optional. This requires that all +// code using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::optional is available. This option +// is useful when you are building your program from source. It should not be +// used otherwise -- for example, if you are distributing Abseil in a binary +// package manager -- since in mode 2, absl::optional will name a different +// type, with a different mangled name and binary layout, depending on the +// compiler flags passed by the end user. For more info, see +// https://abseil.io/about/design/dropin-types. + +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::optional is available. This option +// should not be used when your program is not built from source -- for example, +// if you are distributing Abseil in a binary package manager -- since in mode +// 2, absl::optional will name a different template class, with a different +// mangled name and binary layout, depending on the compiler flags passed by the +// end user. +// +// User code should not inspect this macro. To check in the preprocessor if +// absl::optional is a typedef of std::optional, use the feature macro +// ABSL_USES_STD_OPTIONAL. + +#define ABSL_OPTION_USE_STD_OPTIONAL 2 + + +// ABSL_OPTION_USE_STD_STRING_VIEW +// +// This option controls whether absl::string_view is implemented as an alias to +// std::string_view, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::string_view. This requires that +// all code using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::string_view is available. This +// option is useful when you are building your program from source. It should +// not be used otherwise -- for example, if you are distributing Abseil in a +// binary package manager -- since in mode 2, absl::string_view will name a +// different type, with a different mangled name and binary layout, depending on +// the compiler flags passed by the end user. For more info, see +// https://abseil.io/about/design/dropin-types. +// +// User code should not inspect this macro. To check in the preprocessor if +// absl::string_view is a typedef of std::string_view, use the feature macro +// ABSL_USES_STD_STRING_VIEW. + +#define ABSL_OPTION_USE_STD_STRING_VIEW 2 + + +// ABSL_OPTION_USE_STD_VARIANT +// +// This option controls whether absl::variant is implemented as an alias to +// std::variant, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::variant. This requires that all +// code using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::variant is available. This option +// is useful when you are building your program from source. It should not be +// used otherwise -- for example, if you are distributing Abseil in a binary +// package manager -- since in mode 2, absl::variant will name a different +// type, with a different mangled name and binary layout, depending on the +// compiler flags passed by the end user. For more info, see +// https://abseil.io/about/design/dropin-types. +// +// User code should not inspect this macro. To check in the preprocessor if +// absl::variant is a typedef of std::variant, use the feature macro +// ABSL_USES_STD_VARIANT. + +#define ABSL_OPTION_USE_STD_VARIANT 2 + +#endif // ABSL_BASE_OPTIONS_H_ diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc index 6cff1a25..02d1f879 100644 --- a/absl/container/flat_hash_map_test.cc +++ b/absl/container/flat_hash_map_test.cc @@ -214,7 +214,7 @@ TEST(FlatHashMap, MergeExtractInsert) { EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 17), Pair(2, 9))); } -#if (defined(ABSL_HAVE_STD_ANY) || !defined(_LIBCPP_VERSION)) && \ +#if (defined(ABSL_USES_STD_ANY) || !defined(_LIBCPP_VERSION)) && \ !defined(__EMSCRIPTEN__) TEST(FlatHashMap, Any) { absl::flat_hash_map m; @@ -246,7 +246,7 @@ TEST(FlatHashMap, Any) { ASSERT_NE(it2, m2.end()); EXPECT_EQ(7, it2->second); } -#endif // (defined(ABSL_HAVE_STD_ANY) || !defined(_LIBCPP_VERSION)) && +#endif // (defined(ABSL_USES_STD_ANY) || !defined(_LIBCPP_VERSION)) && // !defined(__EMSCRIPTEN__) } // namespace diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h index 7d08f7e3..f678c88d 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h @@ -471,12 +471,9 @@ auto Storage::Initialize(ValueAdapter values, size_type new_size) // safe to take on the allocation with size `0`. If `ConstructElements(...)` // throws, deallocation will be automatically handled by `~Storage()`. size_type new_capacity = ComputeCapacity(GetInlinedCapacity(), new_size); - pointer new_data = AllocatorTraits::allocate(*GetAllocPtr(), new_capacity); - - SetAllocatedData(new_data, new_capacity); + construct_data = AllocatorTraits::allocate(*GetAllocPtr(), new_capacity); + SetAllocatedData(construct_data, new_capacity); SetIsAllocated(); - - construct_data = new_data; } else { construct_data = GetInlinedData(); } @@ -503,9 +500,7 @@ auto Storage::Assign(ValueAdapter values, size_type new_size) -> void { if (new_size > storage_view.capacity) { size_type new_capacity = ComputeCapacity(storage_view.capacity, new_size); - pointer new_data = allocation_tx.Allocate(new_capacity); - - construct_loop = {new_data, new_size}; + construct_loop = {allocation_tx.Allocate(new_capacity), new_size}; destroy_loop = {storage_view.data, storage_view.size}; } else if (new_size > storage_view.size) { assign_loop = {storage_view.data, storage_view.size}; @@ -552,7 +547,6 @@ auto Storage::Resize(ValueAdapter values, size_type new_size) -> void { if (new_size > storage_view.capacity) { size_type new_capacity = ComputeCapacity(storage_view.capacity, new_size); pointer new_data = allocation_tx.Allocate(new_capacity); - construct_loop = {new_data + storage_view.size, new_size - storage_view.size}; move_construct_loop = {new_data, storage_view.size}; @@ -690,14 +684,14 @@ auto Storage::EmplaceBack(Args&&... args) -> reference { pointer construct_data; if (storage_view.size == storage_view.capacity) { size_type new_capacity = NextCapacity(storage_view.capacity); - pointer new_data = allocation_tx.Allocate(new_capacity); - - construct_data = new_data; + construct_data = allocation_tx.Allocate(new_capacity); } else { construct_data = storage_view.data; } - AllocatorTraits::construct(*GetAllocPtr(), construct_data + storage_view.size, + pointer last_ptr = construct_data + storage_view.size; + + AllocatorTraits::construct(*GetAllocPtr(), last_ptr, std::forward(args)...); if (allocation_tx.DidAllocate()) { @@ -707,8 +701,7 @@ auto Storage::EmplaceBack(Args&&... args) -> reference { storage_view.size); } ABSL_INTERNAL_CATCH_ANY { - AllocatorTraits::destroy(*GetAllocPtr(), - construct_data + storage_view.size); + AllocatorTraits::destroy(*GetAllocPtr(), last_ptr); ABSL_INTERNAL_RETHROW; } @@ -721,7 +714,7 @@ auto Storage::EmplaceBack(Args&&... args) -> reference { } AddSize(1); - return *(construct_data + storage_view.size); + return *last_ptr; } template @@ -793,9 +786,7 @@ auto Storage::ShrinkToFit() -> void { pointer construct_data; if (storage_view.size > GetInlinedCapacity()) { size_type new_capacity = storage_view.size; - pointer new_data = allocation_tx.Allocate(new_capacity); - - construct_data = new_data; + construct_data = allocation_tx.Allocate(new_capacity); } else { construct_data = GetInlinedData(); } diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 9992ba4b..9079a73e 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -668,7 +668,7 @@ class raw_hash_set { } ctrl_t* ctrl_ = nullptr; - // To avoid uninitialized member warnigs, put slot_ in an anonymous union. + // To avoid uninitialized member warnings, put slot_ in an anonymous union. // The member is not initialized on singleton and end iterators. union { slot_type* slot_; diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index 76959cde..d57a8792 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -145,6 +145,18 @@ using IsMoveAssignableImpl = decltype(std::declval() = std::declval()); } // namespace type_traits_internal +// MSVC 19.20 has a regression that causes our workarounds to fail, but their +// std forms now appear to be compliant. +#if defined(_MSC_VER) && !defined(__clang__) && (_MSC_VER >= 1920) + +template +using is_copy_assignable = std::is_copy_assignable; + +template +using is_move_assignable = std::is_move_assignable; + +#else + template struct is_copy_assignable : type_traits_internal::is_detected< type_traits_internal::IsCopyAssignableImpl, T> { @@ -155,6 +167,8 @@ struct is_move_assignable : type_traits_internal::is_detected< type_traits_internal::IsMoveAssignableImpl, T> { }; +#endif + // void_t() // // Ignores the type of any its arguments and returns `void`. In general, this diff --git a/absl/random/internal/nonsecure_base_test.cc b/absl/random/internal/nonsecure_base_test.cc index d9de9901..698027fc 100644 --- a/absl/random/internal/nonsecure_base_test.cc +++ b/absl/random/internal/nonsecure_base_test.cc @@ -154,9 +154,10 @@ TEST(NonsecureURBGBase, CompatibleWithDistributionUtils) { TEST(NonsecureURBGBase, CompatibleWithStdDistributions) { ExampleNonsecureURBG rbg; - std::uniform_int_distribution(0, 100)(rbg); - std::uniform_real_distribution()(rbg); - std::bernoulli_distribution(0.2)(rbg); + // Cast to void to suppress [[nodiscard]] warnings + static_cast(std::uniform_int_distribution(0, 100)(rbg)); + static_cast(std::uniform_real_distribution()(rbg)); + static_cast(std::bernoulli_distribution(0.2)(rbg)); } TEST(NonsecureURBGBase, ConsecutiveDefaultInstancesYieldUniqueVariates) { diff --git a/absl/random/log_uniform_int_distribution.h b/absl/random/log_uniform_int_distribution.h index 956a6907..de58bdbe 100644 --- a/absl/random/log_uniform_int_distribution.h +++ b/absl/random/log_uniform_int_distribution.h @@ -192,13 +192,15 @@ log_uniform_int_distribution::Generate( const double r = std::pow(p.base(), d); const double s = (r * p.base()) - 1.0; - base_e = (r > (std::numeric_limits::max)()) - ? (std::numeric_limits::max)() - : static_cast(r); - - top_e = (s > (std::numeric_limits::max)()) - ? (std::numeric_limits::max)() - : static_cast(s); + base_e = + (r > static_cast((std::numeric_limits::max)())) + ? (std::numeric_limits::max)() + : static_cast(r); + + top_e = + (s > static_cast((std::numeric_limits::max)())) + ? (std::numeric_limits::max)() + : static_cast(s); } const unsigned_type lo = (base_e >= p.range()) ? p.range() : base_e; diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h index 745de67a..9b8ec89a 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -37,7 +37,14 @@ #include #include "absl/base/internal/bits.h" +#ifdef __SSE4_2__ +// TODO(jorg): Remove this when we figure out the right way +// to swap bytes on SSE 4.2 that works with the compilers +// we claim to support. Also, add tests for the compiler +// that doesn't support the Intel _bswap64 intrinsic but +// does support all the SSE 4.2 intrinsics #include "absl/base/internal/endian.h" +#endif #include "absl/base/macros.h" #include "absl/base/port.h" #include "absl/numeric/int128.h" @@ -189,12 +196,12 @@ ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s, int_type* out, // Returns the number of non-pad digits of the output (it can never be zero // since 0 has one digit). inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) { - uint64_t be = absl::big_endian::FromHost64(val); #ifdef __SSE4_2__ + uint64_t be = absl::big_endian::FromHost64(val); const auto kNibbleMask = _mm_set1_epi8(0xf); const auto kHexDigits = _mm_setr_epi8('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); - auto v = _mm_loadu_si64(reinterpret_cast<__m128i*>(&be)); // load lo dword + auto v = _mm_loadl_epi64(reinterpret_cast<__m128i*>(&be)); // load lo dword auto v4 = _mm_srli_epi64(v, 4); // shift 4 right auto il = _mm_unpacklo_epi8(v4, v); // interleave bytes auto m = _mm_and_si128(il, kNibbleMask); // mask out nibbles @@ -202,7 +209,7 @@ inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) { _mm_storeu_si128(reinterpret_cast<__m128i*>(out), hexchars); #else for (int i = 0; i < 8; ++i) { - auto byte = (be >> (8 * i)) & 0xFF; + auto byte = (val >> (56 - 8 * i)) & 0xFF; auto* hex = &absl::numbers_internal::kHexTable[byte * 2]; std::memcpy(out + 2 * i, hex, 2); } diff --git a/absl/strings/str_cat.cc b/absl/strings/str_cat.cc index d5877899..4bd56f5f 100644 --- a/absl/strings/str_cat.cc +++ b/absl/strings/str_cat.cc @@ -27,23 +27,21 @@ namespace absl { AlphaNum::AlphaNum(Hex hex) { + static_assert(numbers_internal::kFastToBufferSize >= 32, + "This function only works when output buffer >= 32 bytes long"); char* const end = &digits_[numbers_internal::kFastToBufferSize]; - char* writer = end; - uint64_t value = hex.value; - do { - *--writer = absl::numbers_internal::kHexChar[value & 0xF]; - value >>= 4; - } while (value != 0); - - char* beg; - if (end - writer < hex.width) { - beg = end - hex.width; - std::fill_n(beg, writer - beg, hex.fill); + auto real_width = + absl::numbers_internal::FastHexToBufferZeroPad16(hex.value, end - 16); + if (real_width >= hex.width) { + piece_ = absl::string_view(end - real_width, real_width); } else { - beg = writer; + // Pad first 16 chars because FastHexToBufferZeroPad16 pads only to 16 and + // max pad width can be up to 20. + std::memset(end - 32, hex.fill, 16); + // Patch up everything else up to the real_width. + std::memset(end - real_width - 16, hex.fill, 16); + piece_ = absl::string_view(end - hex.width, hex.width); } - - piece_ = absl::string_view(beg, end - beg); } AlphaNum::AlphaNum(Dec dec) { diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index 607e2bca..c11c93a2 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -400,6 +400,12 @@ int FPrintF(std::FILE* output, const FormatSpec& format, // This function is functionally equivalent to `std::snprintf()` (and // type-safe); prefer `absl::SNPrintF()` over `std::snprintf()`. // +// In particular, a successful call to `absl::SNPrintF()` writes at most `size` +// bytes of the formatted output to `output`, including a null terminator, and +// returns the number of bytes that would have been written if truncation did +// not occur. In the event of an error, a negative value is returned and `errno` +// is set. +// // Example: // // std::string_view s = "Ulaanbaatar"; diff --git a/absl/strings/string_view.cc b/absl/strings/string_view.cc index dc034a83..d5e1a3de 100644 --- a/absl/strings/string_view.cc +++ b/absl/strings/string_view.cc @@ -14,7 +14,7 @@ #include "absl/strings/string_view.h" -#ifndef ABSL_HAVE_STD_STRING_VIEW +#ifndef ABSL_USES_STD_STRING_VIEW #include #include @@ -230,4 +230,4 @@ constexpr string_view::size_type string_view::kMaxSize; } // namespace absl -#endif // ABSL_HAVE_STD_STRING_VIEW +#endif // ABSL_USES_STD_STRING_VIEW diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 3438ccc1..07075e80 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -30,7 +30,7 @@ #include #include "absl/base/config.h" -#ifdef ABSL_HAVE_STD_STRING_VIEW +#ifdef ABSL_USES_STD_STRING_VIEW #include // IWYU pragma: export @@ -38,7 +38,7 @@ namespace absl { using std::string_view; } // namespace absl -#else // ABSL_HAVE_STD_STRING_VIEW +#else // ABSL_USES_STD_STRING_VIEW #if ABSL_HAVE_BUILTIN(__builtin_memcmp) || \ (defined(__GNUC__) && !defined(__clang__)) @@ -580,7 +580,7 @@ std::ostream& operator<<(std::ostream& o, string_view piece); #undef ABSL_INTERNAL_STRING_VIEW_MEMCMP -#endif // ABSL_HAVE_STD_STRING_VIEW +#endif // ABSL_USES_STD_STRING_VIEW namespace absl { diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc index 86f2fbcd..96dacdf0 100644 --- a/absl/strings/string_view_test.cc +++ b/absl/strings/string_view_test.cc @@ -830,7 +830,7 @@ TEST(StringViewTest, FrontBackSingleChar) { // to the standard, but `absl::string_view` implements a different // behavior for historical reasons. We work around tests that construct // `string_view` from `nullptr` when using libc++. -#if !defined(ABSL_HAVE_STD_STRING_VIEW) || \ +#if !defined(ABSL_USES_STD_STRING_VIEW) || \ (!(defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 9) && \ !defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) #define ABSL_HAVE_STRING_VIEW_FROM_NULLPTR 1 @@ -938,7 +938,7 @@ TEST(StringViewTest, ConstexprCompiles) { #endif constexpr absl::string_view cstr_len("cstr", 4); -#if defined(ABSL_HAVE_STD_STRING_VIEW) +#if defined(ABSL_USES_STD_STRING_VIEW) // In libstdc++ (as of 7.2), `std::string_view::string_view(const char*)` // calls `std::char_traits::length(const char*)` to get the std::string // length, but it is not marked constexpr yet. See GCC bug: @@ -952,7 +952,7 @@ TEST(StringViewTest, ConstexprCompiles) { #define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1 #endif // !__GLIBCXX__ -#else // ABSL_HAVE_STD_STRING_VIEW +#else // ABSL_USES_STD_STRING_VIEW // This duplicates the check for __builtin_strlen in the header. #if ABSL_HAVE_BUILTIN(__builtin_strlen) || \ @@ -967,7 +967,7 @@ TEST(StringViewTest, ConstexprCompiles) { #define ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR 1 #endif -#endif // ABSL_HAVE_STD_STRING_VIEW +#endif // ABSL_USES_STD_STRING_VIEW #ifdef ABSL_HAVE_CONSTEXPR_STRING_VIEW_FROM_CSTR constexpr absl::string_view cstr_strlen("foo"); @@ -1136,7 +1136,7 @@ TEST(HugeStringView, TwoPointTwoGB) { } #endif // THREAD_SANITIZER -#if !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW) +#if !defined(NDEBUG) && !defined(ABSL_USES_STD_STRING_VIEW) TEST(NonNegativeLenTest, NonNegativeLen) { ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("xyz", -1), "len <= kMaxSize"); @@ -1152,7 +1152,7 @@ TEST(LenExceedsMaxSizeTest, LenExceedsMaxSize) { ABSL_EXPECT_DEATH_IF_SUPPORTED(absl::string_view("", max_size + 1), "len <= kMaxSize"); } -#endif // !defined(NDEBUG) && !defined(ABSL_HAVE_STD_STRING_VIEW) +#endif // !defined(NDEBUG) && !defined(ABSL_USES_STD_STRING_VIEW) class StringViewStreamTest : public ::testing::Test { public: diff --git a/absl/synchronization/internal/waiter.cc b/absl/synchronization/internal/waiter.cc index d83d8087..2f41aa5f 100644 --- a/absl/synchronization/internal/waiter.cc +++ b/absl/synchronization/internal/waiter.cc @@ -161,7 +161,7 @@ bool Waiter::Wait(KernelTimeout t) { void Waiter::Post() { if (futex_.fetch_add(1, std::memory_order_release) == 0) { - // We incremented from 0, need to wake a potential waker. + // We incremented from 0, need to wake a potential waiter. Poke(); } } @@ -210,8 +210,8 @@ void Waiter::Init() { ABSL_RAW_LOG(FATAL, "pthread_cond_init failed: %d", err2); } - waiter_count_.store(0, std::memory_order_relaxed); - wakeup_count_.store(0, std::memory_order_relaxed); + waiter_count_ = 0; + wakeup_count_ = 0; } bool Waiter::Wait(KernelTimeout t) { @@ -221,24 +221,12 @@ bool Waiter::Wait(KernelTimeout t) { } PthreadMutexHolder h(&mu_); - waiter_count_.fetch_add(1, std::memory_order_relaxed); + ++waiter_count_; // Loop until we find a wakeup to consume or timeout. // Note that, since the thread ticker is just reset, we don't need to check // whether the thread is idle on the very first pass of the loop. bool first_pass = true; - while (true) { - int x = wakeup_count_.load(std::memory_order_relaxed); - if (x != 0) { - if (!wakeup_count_.compare_exchange_weak(x, x - 1, - std::memory_order_acquire, - std::memory_order_relaxed)) { - continue; // Raced with someone, retry. - } - // Successfully consumed a wakeup, we're done. - waiter_count_.fetch_sub(1, std::memory_order_relaxed); - return true; - } - + while (wakeup_count_ == 0) { if (!first_pass) MaybeBecomeIdle(); // No wakeups available, time to wait. if (!t.has_timeout()) { @@ -249,34 +237,38 @@ bool Waiter::Wait(KernelTimeout t) { } else { const int err = pthread_cond_timedwait(&cv_, &mu_, &abs_timeout); if (err == ETIMEDOUT) { - waiter_count_.fetch_sub(1, std::memory_order_relaxed); + --waiter_count_; return false; } if (err != 0) { - ABSL_RAW_LOG(FATAL, "pthread_cond_wait failed: %d", err); + ABSL_RAW_LOG(FATAL, "pthread_cond_timedwait failed: %d", err); } } first_pass = false; } + // Consume a wakeup and we're done. + --wakeup_count_; + --waiter_count_; + return true; } void Waiter::Post() { - wakeup_count_.fetch_add(1, std::memory_order_release); - Poke(); + PthreadMutexHolder h(&mu_); + ++wakeup_count_; + InternalCondVarPoke(); } void Waiter::Poke() { - if (waiter_count_.load(std::memory_order_relaxed) == 0) { - return; - } - // Potentially a waker. Take the lock and check again. PthreadMutexHolder h(&mu_); - if (waiter_count_.load(std::memory_order_relaxed) == 0) { - return; - } - const int err = pthread_cond_signal(&cv_); - if (err != 0) { - ABSL_RAW_LOG(FATAL, "pthread_cond_signal failed: %d", err); + InternalCondVarPoke(); +} + +void Waiter::InternalCondVarPoke() { + if (waiter_count_ != 0) { + const int err = pthread_cond_signal(&cv_); + if (ABSL_PREDICT_FALSE(err != 0)) { + ABSL_RAW_LOG(FATAL, "pthread_cond_signal failed: %d", err); + } } } @@ -456,7 +448,7 @@ void Waiter::Poke() { if (waiter_count_.load(std::memory_order_relaxed) == 0) { return; } - // Potentially a waker. Take the lock and check again. + // Potentially a waiter. Take the lock and check again. LockHolder h(WinHelper::GetLock(this)); if (waiter_count_.load(std::memory_order_relaxed) == 0) { return; diff --git a/absl/synchronization/internal/waiter.h b/absl/synchronization/internal/waiter.h index 09993545..c2389700 100644 --- a/absl/synchronization/internal/waiter.h +++ b/absl/synchronization/internal/waiter.h @@ -106,10 +106,13 @@ class Waiter { static_assert(sizeof(int32_t) == sizeof(futex_), "Wrong size for futex"); #elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_CONDVAR + // REQUIRES: mu_ must be held. + void InternalCondVarPoke(); + pthread_mutex_t mu_; pthread_cond_t cv_; - std::atomic waiter_count_; - std::atomic wakeup_count_; // Unclaimed wakeups, written under lock. + int waiter_count_; + int wakeup_count_; // Unclaimed wakeups. #elif ABSL_WAITER_MODE == ABSL_WAITER_MODE_SEM sem_t sem_; diff --git a/absl/synchronization/lifetime_test.cc b/absl/synchronization/lifetime_test.cc index 34b8875b..cc973a32 100644 --- a/absl/synchronization/lifetime_test.cc +++ b/absl/synchronization/lifetime_test.cc @@ -122,6 +122,11 @@ class OnDestruction { Function fn_; }; +// These tests require that the compiler correctly supports C++11 constant +// initialization... but MSVC has a known regression since v19.10: +// https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html +// TODO(epastor): Limit the affected range once MSVC fixes this bug. +#if defined(__clang__) || !(defined(_MSC_VER) && _MSC_VER > 1900) // kConstInit // Test early usage. (Declaration comes first; definitions must appear after // the test runner.) @@ -151,6 +156,7 @@ OnConstruction check_still_locked([]() ABSL_NO_THREAD_SAFETY_ANALYSIS { const_init_sanity_mutex.AssertHeld(); const_init_sanity_mutex.Unlock(); }); +#endif // defined(__clang__) || !(defined(_MSC_VER) && _MSC_VER > 1900) // Test shutdown usage. (Declarations come first; definitions must appear after // the test runner.) diff --git a/absl/time/civil_time.h b/absl/time/civil_time.h index c8166d07..77c3be2e 100644 --- a/absl/time/civil_time.h +++ b/absl/time/civil_time.h @@ -519,7 +519,7 @@ namespace time_internal { // For functions found via ADL on civil-time tags. // // Example: // -// absl::CivilDay d = absl::CivilDay("1969-07-20"); +// absl::CivilDay d = absl::CivilDay(1969, 7, 20); // std::cout << "Date is: " << d << "\n"; // std::ostream& operator<<(std::ostream& os, CivilYear y); diff --git a/absl/time/duration.cc b/absl/time/duration.cc index 9a876811..f0b4631d 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc @@ -197,11 +197,11 @@ inline int64_t DecodeTwosComp(uint64_t v) { return absl::bit_cast(v); } // double as overflow cases. inline bool SafeAddRepHi(double a_hi, double b_hi, Duration* d) { double c = a_hi + b_hi; - if (c >= kint64max) { + if (c >= static_cast(kint64max)) { *d = InfiniteDuration(); return false; } - if (c <= kint64min) { + if (c <= static_cast(kint64min)) { *d = -InfiniteDuration(); return false; } diff --git a/absl/time/time.h b/absl/time/time.h index 0b7312ee..46ac26b3 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -422,7 +422,9 @@ Duration Milliseconds(T n) { template = 0> Duration Seconds(T n) { if (n >= 0) { // Note: `NaN >= 0` is false. - if (n >= (std::numeric_limits::max)()) return InfiniteDuration(); + if (n >= static_cast((std::numeric_limits::max)())) { + return InfiniteDuration(); + } return time_internal::MakePosDoubleDuration(n); } else { if (std::isnan(n)) diff --git a/absl/types/any.h b/absl/types/any.h index 507c8b2c..f7967694 100644 --- a/absl/types/any.h +++ b/absl/types/any.h @@ -56,7 +56,7 @@ #include "absl/base/config.h" #include "absl/utility/utility.h" -#ifdef ABSL_HAVE_STD_ANY +#ifdef ABSL_USES_STD_ANY #include // IWYU pragma: export @@ -67,7 +67,7 @@ using std::bad_any_cast; using std::make_any; } // namespace absl -#else // ABSL_HAVE_STD_ANY +#else // ABSL_USES_STD_ANY #include #include @@ -538,6 +538,6 @@ T* any_cast(any* operand) noexcept { #undef ABSL_ANY_DETAIL_HAS_RTTI -#endif // ABSL_HAVE_STD_ANY +#endif // ABSL_USES_STD_ANY #endif // ABSL_TYPES_ANY_H_ diff --git a/absl/types/any_exception_safety_test.cc b/absl/types/any_exception_safety_test.cc index 17d7f5d7..31c11401 100644 --- a/absl/types/any_exception_safety_test.cc +++ b/absl/types/any_exception_safety_test.cc @@ -18,7 +18,7 @@ // This test is a no-op when absl::any is an alias for std::any and when // exceptions are not enabled. -#if !defined(ABSL_HAVE_STD_ANY) && defined(ABSL_HAVE_EXCEPTIONS) +#if !defined(ABSL_USES_STD_ANY) && defined(ABSL_HAVE_EXCEPTIONS) #include #include @@ -170,4 +170,4 @@ TEST(AnyExceptionSafety, Emplace) { } // namespace -#endif // #if !defined(ABSL_HAVE_STD_ANY) && defined(ABSL_HAVE_EXCEPTIONS) +#endif // #if !defined(ABSL_USES_STD_ANY) && defined(ABSL_HAVE_EXCEPTIONS) diff --git a/absl/types/any_test.cc b/absl/types/any_test.cc index 4a848ae4..70e4ba22 100644 --- a/absl/types/any_test.cc +++ b/absl/types/any_test.cc @@ -15,7 +15,7 @@ #include "absl/types/any.h" // This test is a no-op when absl::any is an alias for std::any. -#if !defined(ABSL_HAVE_STD_ANY) +#if !defined(ABSL_USES_STD_ANY) #include #include @@ -642,7 +642,7 @@ TEST(AnyTest, ConversionConstructionCausesOneCopy) { // Tests for Exception Behavior // ////////////////////////////////// -#if defined(ABSL_HAVE_STD_ANY) +#if defined(ABSL_USES_STD_ANY) // If using a std `any` implementation, we can't check for a specific message. #define ABSL_ANY_TEST_EXPECT_BAD_ANY_CAST(...) \ @@ -656,7 +656,7 @@ TEST(AnyTest, ConversionConstructionCausesOneCopy) { ABSL_BASE_INTERNAL_EXPECT_FAIL((__VA_ARGS__), absl::bad_any_cast, \ "Bad any cast") -#endif // defined(ABSL_HAVE_STD_ANY) +#endif // defined(ABSL_USES_STD_ANY) TEST(AnyTest, ThrowBadAlloc) { { @@ -764,7 +764,7 @@ TEST(AnyTest, FailedEmplace) { BadCopyable bad; absl::any target(absl::in_place_type); ABSL_ANY_TEST_EXPECT_BAD_COPY(target.emplace(bad)); -#if defined(ABSL_HAVE_STD_ANY) && defined(__GLIBCXX__) +#if defined(ABSL_USES_STD_ANY) && defined(__GLIBCXX__) // libstdc++ std::any::emplace() implementation (as of 7.2) has a bug: if an // exception is thrown, *this contains a value. #define ABSL_GLIBCXX_ANY_EMPLACE_EXCEPTION_BUG 1 @@ -778,4 +778,4 @@ TEST(AnyTest, FailedEmplace) { } // namespace -#endif // #if !defined(ABSL_HAVE_STD_ANY) +#endif // #if !defined(ABSL_USES_STD_ANY) diff --git a/absl/types/bad_any_cast.cc b/absl/types/bad_any_cast.cc index 505919a5..2a538126 100644 --- a/absl/types/bad_any_cast.cc +++ b/absl/types/bad_any_cast.cc @@ -14,7 +14,7 @@ #include "absl/types/bad_any_cast.h" -#ifndef ABSL_HAVE_STD_ANY +#ifndef ABSL_USES_STD_ANY #include @@ -41,4 +41,4 @@ void ThrowBadAnyCast() { } // namespace any_internal } // namespace absl -#endif // ABSL_HAVE_STD_ANY +#endif // ABSL_USES_STD_ANY diff --git a/absl/types/bad_any_cast.h b/absl/types/bad_any_cast.h index 8d020ede..6a53c010 100644 --- a/absl/types/bad_any_cast.h +++ b/absl/types/bad_any_cast.h @@ -25,7 +25,7 @@ #include "absl/base/config.h" -#ifdef ABSL_HAVE_STD_ANY +#ifdef ABSL_USES_STD_ANY #include @@ -33,7 +33,7 @@ namespace absl { using std::bad_any_cast; } // namespace absl -#else // ABSL_HAVE_STD_ANY +#else // ABSL_USES_STD_ANY namespace absl { @@ -66,6 +66,6 @@ namespace any_internal { } // namespace any_internal } // namespace absl -#endif // ABSL_HAVE_STD_ANY +#endif // ABSL_USES_STD_ANY #endif // ABSL_TYPES_BAD_ANY_CAST_H_ diff --git a/absl/types/bad_optional_access.cc b/absl/types/bad_optional_access.cc index a791c7c2..d9ec21bf 100644 --- a/absl/types/bad_optional_access.cc +++ b/absl/types/bad_optional_access.cc @@ -14,7 +14,7 @@ #include "absl/types/bad_optional_access.h" -#ifndef ABSL_HAVE_STD_OPTIONAL +#ifndef ABSL_USES_STD_OPTIONAL #include @@ -43,4 +43,4 @@ void throw_bad_optional_access() { } // namespace optional_internal } // namespace absl -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL diff --git a/absl/types/bad_optional_access.h b/absl/types/bad_optional_access.h index add5c452..32dd6a91 100644 --- a/absl/types/bad_optional_access.h +++ b/absl/types/bad_optional_access.h @@ -25,7 +25,7 @@ #include "absl/base/config.h" -#ifdef ABSL_HAVE_STD_OPTIONAL +#ifdef ABSL_USES_STD_OPTIONAL #include @@ -33,7 +33,7 @@ namespace absl { using std::bad_optional_access; } // namespace absl -#else // ABSL_HAVE_STD_OPTIONAL +#else // ABSL_USES_STD_OPTIONAL namespace absl { @@ -69,6 +69,6 @@ namespace optional_internal { } // namespace optional_internal } // namespace absl -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL #endif // ABSL_TYPES_BAD_OPTIONAL_ACCESS_H_ diff --git a/absl/types/bad_variant_access.cc b/absl/types/bad_variant_access.cc index a4325c8d..dbaea9e9 100644 --- a/absl/types/bad_variant_access.cc +++ b/absl/types/bad_variant_access.cc @@ -14,7 +14,7 @@ #include "absl/types/bad_variant_access.h" -#ifndef ABSL_HAVE_STD_VARIANT +#ifndef ABSL_USES_STD_VARIANT #include #include @@ -59,4 +59,4 @@ void Rethrow() { } // namespace variant_internal } // namespace absl -#endif // ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_VARIANT diff --git a/absl/types/bad_variant_access.h b/absl/types/bad_variant_access.h index 637db435..6935d01b 100644 --- a/absl/types/bad_variant_access.h +++ b/absl/types/bad_variant_access.h @@ -25,7 +25,7 @@ #include "absl/base/config.h" -#ifdef ABSL_HAVE_STD_VARIANT +#ifdef ABSL_USES_STD_VARIANT #include @@ -33,7 +33,7 @@ namespace absl { using std::bad_variant_access; } // namespace absl -#else // ABSL_HAVE_STD_VARIANT +#else // ABSL_USES_STD_VARIANT namespace absl { @@ -73,6 +73,6 @@ namespace variant_internal { } // namespace variant_internal } // namespace absl -#endif // ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_VARIANT #endif // ABSL_TYPES_BAD_VARIANT_ACCESS_H_ diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h index 19de2e13..58b38592 100644 --- a/absl/types/internal/variant.h +++ b/absl/types/internal/variant.h @@ -37,7 +37,7 @@ #include "absl/types/bad_variant_access.h" #include "absl/utility/utility.h" -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) namespace absl { @@ -1640,5 +1640,5 @@ struct VariantHashBase // IWYU pragma: export @@ -50,7 +50,7 @@ using std::nullopt_t; using std::nullopt; } // namespace absl -#else // ABSL_HAVE_STD_OPTIONAL +#else // ABSL_USES_STD_OPTIONAL #include #include @@ -767,6 +767,6 @@ struct hash > #undef ABSL_MSVC_CONSTEXPR_BUG_IN_UNION_LIKE_CLASS -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL #endif // ABSL_TYPES_OPTIONAL_H_ diff --git a/absl/types/optional_exception_safety_test.cc b/absl/types/optional_exception_safety_test.cc index f99e35c0..0f7fae6c 100644 --- a/absl/types/optional_exception_safety_test.cc +++ b/absl/types/optional_exception_safety_test.cc @@ -18,7 +18,7 @@ // This test is a no-op when absl::optional is an alias for std::optional and // when exceptions are not enabled. -#if !defined(ABSL_HAVE_STD_OPTIONAL) && defined(ABSL_HAVE_EXCEPTIONS) +#if !defined(ABSL_USES_STD_OPTIONAL) && defined(ABSL_HAVE_EXCEPTIONS) #include "gtest/gtest.h" #include "absl/base/internal/exception_safety_testing.h" @@ -287,4 +287,4 @@ TEST(OptionalExceptionSafety, NothrowMoveAssign) { } // namespace absl -#endif // #if !defined(ABSL_HAVE_STD_OPTIONAL) && defined(ABSL_HAVE_EXCEPTIONS) +#endif // #if !defined(ABSL_USES_STD_OPTIONAL) && defined(ABSL_HAVE_EXCEPTIONS) diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc index 35efa863..47d5c8a2 100644 --- a/absl/types/optional_test.cc +++ b/absl/types/optional_test.cc @@ -15,7 +15,7 @@ #include "absl/types/optional.h" // This test is a no-op when absl::optional is an alias for std::optional. -#if !defined(ABSL_HAVE_STD_OPTIONAL) +#if !defined(ABSL_USES_STD_OPTIONAL) #include #include @@ -224,7 +224,7 @@ TEST(optionalTest, CopyConstructor) { EXPECT_FALSE( absl::is_trivially_copy_constructible>::value); -#if defined(ABSL_HAVE_STD_OPTIONAL) && defined(__GLIBCXX__) +#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 is not trivially copyable (due to one of // its base class is unconditionally nontrivial). @@ -279,7 +279,7 @@ TEST(optionalTest, CopyConstructor) { // std::optional when T is volatile-qualified. So skipping this test. // Bug report: // https://connect.microsoft.com/VisualStudio/feedback/details/3142534 -#if defined(ABSL_HAVE_STD_OPTIONAL) && defined(_MSC_VER) && _MSC_VER >= 1911 +#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 @@ -305,7 +305,7 @@ TEST(optionalTest, MoveConstructor) { EXPECT_FALSE(std::is_move_constructible>::value); // test noexcept EXPECT_TRUE(std::is_nothrow_move_constructible>::value); -#ifndef ABSL_HAVE_STD_OPTIONAL +#ifndef ABSL_USES_STD_OPTIONAL EXPECT_EQ( absl::default_allocator_is_nothrow::value, std::is_nothrow_move_constructible>::value); @@ -639,7 +639,7 @@ TEST(optionalTest, CopyAssignment) { EXPECT_FALSE(absl::is_trivially_copy_assignable::value); // std::optional doesn't support volatile nontrivial types. -#ifndef ABSL_HAVE_STD_OPTIONAL +#ifndef ABSL_USES_STD_OPTIONAL { StructorListener listener; Listenable::listener = &listener; @@ -658,7 +658,7 @@ TEST(optionalTest, CopyAssignment) { EXPECT_EQ(1, listener.destruct); EXPECT_EQ(1, listener.volatile_copy_assign); } -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL } TEST(optionalTest, MoveAssignment) { @@ -682,7 +682,7 @@ TEST(optionalTest, MoveAssignment) { EXPECT_EQ(1, listener.move_assign); } // std::optional doesn't support volatile nontrivial types. -#ifndef ABSL_HAVE_STD_OPTIONAL +#ifndef ABSL_USES_STD_OPTIONAL { StructorListener listener; Listenable::listener = &listener; @@ -702,7 +702,7 @@ TEST(optionalTest, MoveAssignment) { EXPECT_EQ(1, listener.destruct); EXPECT_EQ(1, listener.volatile_move_assign); } -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL EXPECT_FALSE(absl::is_move_assignable>::value); EXPECT_TRUE(absl::is_move_assignable>::value); EXPECT_TRUE(absl::is_move_assignable>::value); @@ -1560,7 +1560,7 @@ TEST(optionalTest, NoExcept) { static_assert( std::is_nothrow_move_constructible>::value, ""); -#ifndef ABSL_HAVE_STD_OPTIONAL +#ifndef ABSL_USES_STD_OPTIONAL static_assert(absl::default_allocator_is_nothrow::value == std::is_nothrow_move_constructible< absl::optional>::value, @@ -1658,4 +1658,4 @@ TEST(optionalTest, InPlaceTSFINAEBug) { } // namespace -#endif // #if !defined(ABSL_HAVE_STD_OPTIONAL) +#endif // #if !defined(ABSL_USES_STD_OPTIONAL) diff --git a/absl/types/variant.h b/absl/types/variant.h index 7ef7f88c..f3558703 100644 --- a/absl/types/variant.h +++ b/absl/types/variant.h @@ -45,7 +45,7 @@ #include "absl/base/config.h" #include "absl/utility/utility.h" -#ifdef ABSL_HAVE_STD_VARIANT +#ifdef ABSL_USES_STD_VARIANT #include // IWYU pragma: export @@ -64,7 +64,7 @@ using std::variant_size_v; using std::visit; } // namespace absl -#else // ABSL_HAVE_STD_VARIANT +#else // ABSL_USES_STD_VARIANT #include #include @@ -812,7 +812,7 @@ struct hash> } // namespace std -#endif // ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_VARIANT namespace absl { namespace variant_internal { diff --git a/absl/types/variant_exception_safety_test.cc b/absl/types/variant_exception_safety_test.cc index fd7e6c7f..b486a71e 100644 --- a/absl/types/variant_exception_safety_test.cc +++ b/absl/types/variant_exception_safety_test.cc @@ -18,7 +18,7 @@ // This test is a no-op when absl::variant is an alias for std::variant and when // exceptions are not enabled. -#if !defined(ABSL_HAVE_STD_VARIANT) && defined(ABSL_HAVE_EXCEPTIONS) +#if !defined(ABSL_USES_STD_VARIANT) && defined(ABSL_HAVE_EXCEPTIONS) #include #include @@ -237,7 +237,7 @@ TEST(VariantExceptionSafetyTest, CopyAssign) { } // libstdc++ std::variant has bugs on copy assignment regarding exception // safety. -#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#if !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) // index() != j // if is_nothrow_copy_constructible_v or // !is_nothrow_move_constructible is true, equivalent to @@ -268,7 +268,7 @@ TEST(VariantExceptionSafetyTest, CopyAssign) { .Test()); EXPECT_FALSE(tester.WithContracts(strong_guarantee).Test()); } -#endif // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#endif // !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) { // is_nothrow_copy_constructible_v == false && // is_nothrow_move_constructible_v == true @@ -325,7 +325,7 @@ TEST(VariantExceptionSafetyTest, MoveAssign) { // The fix is targeted for gcc-9. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87431#c7 // https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=267614 -#if !(defined(ABSL_HAVE_STD_VARIANT) && \ +#if !(defined(ABSL_USES_STD_VARIANT) && \ defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE == 8) // - otherwise (index() != j), equivalent to // emplace(get(std::move(rhs))) @@ -342,7 +342,7 @@ TEST(VariantExceptionSafetyTest, MoveAssign) { auto copy = rhs; *lhs = std::move(copy); })); -#endif // !(defined(ABSL_HAVE_STD_VARIANT) && +#endif // !(defined(ABSL_USES_STD_VARIANT) && // defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE == 8) } } @@ -445,7 +445,7 @@ TEST(VariantExceptionSafetyTest, ValueAssign) { // and operator=(variant&&) invokes Tj's move ctor which doesn't throw. // libstdc++ std::variant has bugs on conversion assignment regarding // exception safety. -#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#if !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) { MoveNothrow rhs; EXPECT_TRUE(MakeExceptionSafetyTester() @@ -453,7 +453,7 @@ TEST(VariantExceptionSafetyTest, ValueAssign) { .WithContracts(VariantInvariants, strong_guarantee) .Test([&rhs](ThrowingVariant* lhs) { *lhs = rhs; })); } -#endif // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#endif // !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) } TEST(VariantExceptionSafetyTest, Emplace) { @@ -527,4 +527,4 @@ TEST(VariantExceptionSafetyTest, Swap) { #endif // !defined(ABSL_INTERNAL_MSVC_2017_DBG_MODE) -#endif // #if !defined(ABSL_HAVE_STD_VARIANT) && defined(ABSL_HAVE_EXCEPTIONS) +#endif // #if !defined(ABSL_USES_STD_VARIANT) && defined(ABSL_HAVE_EXCEPTIONS) diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc index b5912745..2913775a 100644 --- a/absl/types/variant_test.cc +++ b/absl/types/variant_test.cc @@ -20,7 +20,7 @@ #include "absl/types/variant.h" // This test is a no-op when absl::variant is an alias for std::variant. -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) #include #include @@ -842,7 +842,7 @@ TEST(VariantTest, TestBackupAssign) { } // libstdc++ doesn't pass this test -#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#if !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) EXPECT_EQ(3, counter[0]); EXPECT_EQ(2, counter[1]); EXPECT_EQ(2, counter[2]); @@ -1933,7 +1933,7 @@ TEST(VariantTest, VisitReferenceWrapper) { } // libstdc++ std::variant doesn't support the INVOKE semantics. -#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#if !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) TEST(VariantTest, VisitMemberFunction) { absl::variant> p(absl::make_unique()); absl::variant> cp( @@ -1957,7 +1957,7 @@ TEST(VariantTest, VisitDataMember) { EXPECT_EQ(42, absl::visit(&Class::member, cp)); } -#endif // !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#endif // !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) ///////////////////////// // [variant.monostate] // @@ -2035,7 +2035,7 @@ TEST(VariantTest, NonmemberSwap) { std::swap(a, b); EXPECT_THAT(a, VariantWith(v2)); EXPECT_THAT(b, VariantWith(v1)); -#ifndef ABSL_HAVE_STD_VARIANT +#ifndef ABSL_USES_STD_VARIANT EXPECT_FALSE(absl::get(a).special_swap); #endif @@ -2083,7 +2083,7 @@ TEST(VariantTest, Hash) { // MSVC std::hash does not use the index, thus produce the same // result on the same value as different alternative. -#if !(defined(_MSC_VER) && defined(ABSL_HAVE_STD_VARIANT)) +#if !(defined(_MSC_VER) && defined(ABSL_USES_STD_VARIANT)) { // same value as different alternative variant v0(in_place_index<0>, 42); @@ -2091,7 +2091,7 @@ TEST(VariantTest, Hash) { std::hash> hash; EXPECT_NE(hash(v0), hash(v1)); } -#endif // !(defined(_MSC_VER) && defined(ABSL_HAVE_STD_VARIANT)) +#endif // !(defined(_MSC_VER) && defined(ABSL_USES_STD_VARIANT)) { std::hash> hash; @@ -2118,7 +2118,7 @@ TEST(VariantTest, Hash) { //////////////////////////////////////// // Test that a set requiring a basic type conversion works correctly -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) TEST(VariantTest, TestConvertingSet) { typedef variant Variant; Variant v(1.0); @@ -2128,7 +2128,7 @@ TEST(VariantTest, TestConvertingSet) { ASSERT_TRUE(nullptr != absl::get_if(&v)); EXPECT_DOUBLE_EQ(2, absl::get(v)); } -#endif // ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_VARIANT // Test that a vector of variants behaves reasonably. TEST(VariantTest, Container) { @@ -2280,7 +2280,7 @@ struct Convertible2 { }; TEST(VariantTest, TestRvalueConversion) { -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) variant var( ConvertVariantTo>( variant(0))); @@ -2313,7 +2313,7 @@ TEST(VariantTest, TestRvalueConversion) { variant2 = ConvertVariantTo>(variant(42)); ASSERT_TRUE(absl::holds_alternative(variant2)); EXPECT_EQ(42, absl::get(variant2)); -#endif // !ABSL_HAVE_STD_VARIANT +#endif // !ABSL_USES_STD_VARIANT variant variant3( ConvertVariantTo>( @@ -2326,7 +2326,7 @@ TEST(VariantTest, TestRvalueConversion) { } TEST(VariantTest, TestLvalueConversion) { -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) variant source1 = 0; variant destination( ConvertVariantTo>(source1)); @@ -2428,7 +2428,7 @@ TEST(VariantTest, DoesNotMoveFromLvalues) { } TEST(VariantTest, TestRvalueConversionViaConvertVariantTo) { -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) variant var( ConvertVariantTo>( variant(3))); @@ -2467,7 +2467,7 @@ TEST(VariantTest, TestRvalueConversionViaConvertVariantTo) { } TEST(VariantTest, TestLvalueConversionViaConvertVariantTo) { -#if !defined(ABSL_HAVE_STD_VARIANT) +#if !defined(ABSL_USES_STD_VARIANT) variant source1 = 3; variant destination( ConvertVariantTo>(source1)); @@ -2499,7 +2499,7 @@ TEST(VariantTest, TestLvalueConversionViaConvertVariantTo) { variant source6(42); variant2 = ConvertVariantTo>(source6); EXPECT_THAT(absl::get_if(&variant2), Pointee(42)); -#endif // !ABSL_HAVE_STD_VARIANT +#endif // !ABSL_USES_STD_VARIANT variant source7((Convertible1())); variant variant3( @@ -2533,7 +2533,7 @@ TEST(VariantTest, TestMoveConversionViaConvertVariantTo) { // standard and we know that libstdc++ variant doesn't have this feature. // For more details see the paper: // http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0602r0.html -#if !(defined(ABSL_HAVE_STD_VARIANT) && defined(__GLIBCXX__)) +#if !(defined(ABSL_USES_STD_VARIANT) && defined(__GLIBCXX__)) #define ABSL_VARIANT_PROPAGATE_COPY_MOVE_TRIVIALITY 1 #endif @@ -2711,4 +2711,4 @@ TEST(VariantTest, MoveCtorBug) { } // namespace } // namespace absl -#endif // #if !defined(ABSL_HAVE_STD_VARIANT) +#endif // #if !defined(ABSL_USES_STD_VARIANT) diff --git a/absl/utility/utility.h b/absl/utility/utility.h index eef8fb41..5a98c2c3 100644 --- a/absl/utility/utility.h +++ b/absl/utility/utility.h @@ -158,12 +158,12 @@ using index_sequence_for = make_index_sequence; // Tag types -#ifdef ABSL_HAVE_STD_OPTIONAL +#ifdef ABSL_USES_STD_OPTIONAL using std::in_place_t; using std::in_place; -#else // ABSL_HAVE_STD_OPTIONAL +#else // ABSL_USES_STD_OPTIONAL // in_place_t // @@ -174,9 +174,9 @@ struct in_place_t {}; ABSL_INTERNAL_INLINE_CONSTEXPR(in_place_t, in_place, {}); -#endif // ABSL_HAVE_STD_OPTIONAL +#endif // ABSL_USES_STD_OPTIONAL -#if defined(ABSL_HAVE_STD_ANY) || defined(ABSL_HAVE_STD_VARIANT) +#if defined(ABSL_USES_STD_ANY) || defined(ABSL_USES_STD_VARIANT) using std::in_place_type; using std::in_place_type_t; #else @@ -191,9 +191,9 @@ using in_place_type_t = void (*)(utility_internal::InPlaceTypeTag); template void in_place_type(utility_internal::InPlaceTypeTag) {} -#endif // ABSL_HAVE_STD_ANY || ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_ANY || ABSL_USES_STD_VARIANT -#ifdef ABSL_HAVE_STD_VARIANT +#ifdef ABSL_USES_STD_VARIANT using std::in_place_index; using std::in_place_index_t; #else @@ -208,7 +208,7 @@ using in_place_index_t = void (*)(utility_internal::InPlaceIndexTag); template void in_place_index(utility_internal::InPlaceIndexTag) {} -#endif // ABSL_HAVE_STD_VARIANT +#endif // ABSL_USES_STD_VARIANT // Constexpr move and forward -- cgit v1.2.3 From 8ba96a8244bbe334d09542e92d566673a65c1f78 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 19 Nov 2019 14:43:59 -0800 Subject: Export of internal Abseil changes -- 87f85071a96c6d10f471cdf8a8c2d6c550c926e0 by Matt Kulukundis : Expose ABSL_HAVE_SOURCE_LOCATION_CURRENT as a public api. PiperOrigin-RevId: 281383411 GitOrigin-RevId: 87f85071a96c6d10f471cdf8a8c2d6c550c926e0 Change-Id: I4dfc18a5ba8e064bf9b749892aa8293470459e6b --- absl/base/config.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index 46a84f1a..556b186c 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -85,6 +85,12 @@ #define ABSL_HAVE_BUILTIN(x) 0 #endif +#if defined(__is_identifier) +#define ABSL_INTERNAL_HAS_KEYWORD(x) !(__is_identifier(x)) +#else +#define ABSL_INTERNAL_HAS_KEYWORD(x) 0 +#endif + // ABSL_HAVE_TLS is defined to 1 when __thread should be supported. // We assume __thread is supported on Linux when compiled with Clang or compiled // against libstdc++ with _GLIBCXX_HAVE_TLS defined. @@ -133,6 +139,17 @@ #define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 #endif +// ABSL_HAVE_SOURCE_LOCATION_CURRENT +// +// Indicates whether `absl::SourceLocation::current()` will return useful +// information in some contexts. +#ifndef ABSL_HAVE_SOURCE_LOCATION_CURRENT +#if ABSL_INTERNAL_HAS_KEYWORD(__builtin_LINE) && \ + ABSL_INTERNAL_HAS_KEYWORD(__builtin_FILE) +#define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1 +#endif +#endif + // ABSL_HAVE_THREAD_LOCAL // // Checks whether C++11's `thread_local` storage duration specifier is @@ -539,4 +556,6 @@ #define ABSL_INTERNAL_MSVC_2017_DBG_MODE #endif +#undef ABSL_INTERNAL_HAS_KEYWORD + #endif // ABSL_BASE_CONFIG_H_ -- cgit v1.2.3 From 1e39f8626a4dadec1f56920b999dd4c3cfae333e Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 10 Dec 2019 09:03:32 -0800 Subject: Export of internal Abseil changes -- b842b7fd9b1289be31f0b7ee8e62e48e550747cf by Greg Falcon : Change the Cord str_format formatter to use iteration instead of CordReader. When Cord is publicly released, CordReader is not going with it. PiperOrigin-RevId: 284780736 -- 28e76c08ea7185a7ff9f4e0e02ae565fbbf7980f by Greg Falcon : Implementation detail change. Introduce ABSL_NAMESPACE_BEGIN and _END annotation macros which indicate the beginning and end of a `namespace absl` scope. Currently these do nothing, but they will be used to inject an inline namespace for LTS builds (to avoid symbol collisions against other Abseil versions). These macros should not be used by end users, because end users should never write `namespace absl {` in their own code. This CL applies these annotations to all code under //absl/base/. The rest of Abseil will be annotated in this way in follow-up CLs. PiperOrigin-RevId: 284776410 -- e1711dc6d696dcca50d4e7d4b4d8f3076575b7ec by Abseil Team : --help changed to report long flags. PiperOrigin-RevId: 284757720 -- 78f66a68f428bbbd19d8d60e1125f43ba765fd35 by Tom Manshreck : Update comment on + or - in SimpleAToi() PiperOrigin-RevId: 284231843 GitOrigin-RevId: b842b7fd9b1289be31f0b7ee8e62e48e550747cf Change-Id: I3046b31391bd11c8bc4abab7785a863c377cd757 --- absl/base/BUILD.bazel | 22 ++++++-- absl/base/CMakeLists.txt | 6 ++ absl/base/bit_cast_test.cc | 2 + absl/base/call_once.h | 2 + absl/base/call_once_test.cc | 2 + absl/base/casts.h | 2 + absl/base/config.h | 27 +++++++++ absl/base/const_init.h | 4 ++ absl/base/inline_variable_test.cc | 2 + absl/base/inline_variable_test_a.cc | 2 + absl/base/inline_variable_test_b.cc | 2 + absl/base/internal/atomic_hook.h | 4 ++ absl/base/internal/atomic_hook_test_helper.cc | 2 + absl/base/internal/atomic_hook_test_helper.h | 2 + absl/base/internal/bits.h | 4 ++ absl/base/internal/cycleclock.cc | 2 + absl/base/internal/cycleclock.h | 4 ++ absl/base/internal/direct_mmap.h | 4 ++ absl/base/internal/endian.h | 2 + absl/base/internal/endian_test.cc | 2 + absl/base/internal/exponential_biased.cc | 2 + absl/base/internal/exponential_biased.h | 3 + absl/base/internal/exponential_biased_test.cc | 2 + absl/base/internal/hide_ptr.h | 4 ++ absl/base/internal/identity.h | 4 ++ absl/base/internal/inline_variable_testing.h | 2 + absl/base/internal/invoke.h | 2 + absl/base/internal/low_level_alloc.cc | 2 + absl/base/internal/low_level_alloc.h | 2 + absl/base/internal/low_level_alloc_test.cc | 2 + absl/base/internal/low_level_scheduling.h | 2 + absl/base/internal/periodic_sampler.cc | 2 + absl/base/internal/periodic_sampler.h | 2 + absl/base/internal/periodic_sampler_benchmark.cc | 2 + absl/base/internal/periodic_sampler_test.cc | 2 + absl/base/internal/raw_logging.cc | 2 + absl/base/internal/raw_logging.h | 2 + absl/base/internal/scheduling_mode.h | 4 ++ absl/base/internal/scoped_set_env.cc | 2 + absl/base/internal/scoped_set_env.h | 4 ++ absl/base/internal/spinlock.cc | 2 + absl/base/internal/spinlock.h | 2 + absl/base/internal/spinlock_wait.cc | 2 + absl/base/internal/spinlock_wait.h | 2 + absl/base/internal/sysinfo.cc | 2 + absl/base/internal/sysinfo.h | 2 + absl/base/internal/sysinfo_test.cc | 2 + absl/base/internal/thread_identity.cc | 2 + absl/base/internal/thread_identity.h | 2 + absl/base/internal/thread_identity_test.cc | 2 + absl/base/internal/throw_delegate.cc | 2 + absl/base/internal/throw_delegate.h | 4 ++ absl/base/internal/unaligned_access.h | 6 ++ absl/base/internal/unscaledcycleclock.cc | 2 + absl/base/internal/unscaledcycleclock.h | 2 + absl/base/invoke_test.cc | 2 + absl/base/log_severity.cc | 2 + absl/base/log_severity.h | 3 + absl/base/macros.h | 4 ++ absl/base/spinlock_test_common.cc | 2 + absl/base/thread_annotations.h | 3 + absl/flags/internal/usage.cc | 2 +- absl/flags/internal/usage_test.cc | 70 ++++++++++++------------ absl/strings/internal/str_format/arg.h | 19 ++++--- absl/strings/numbers.h | 17 +++--- 65 files changed, 253 insertions(+), 55 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index f8eb8aeb..e2068f51 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -34,6 +34,7 @@ cc_library( visibility = [ "//absl:__subpackages__", ], + deps = [":config"], ) cc_library( @@ -42,7 +43,10 @@ cc_library( hdrs = ["log_severity.h"], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, - deps = [":core_headers"], + deps = [ + ":config", + ":core_headers", + ], ) cc_library( @@ -165,6 +169,7 @@ cc_library( "//absl:__subpackages__", ], deps = [ + ":config", "//absl/meta:type_traits", ], ) @@ -545,7 +550,10 @@ cc_library( visibility = [ "//absl:__subpackages__", ], - deps = [":core_headers"], + deps = [ + ":config", + ":core_headers", + ], ) cc_test( @@ -568,7 +576,10 @@ cc_library( visibility = [ "//absl:__subpackages__", ], - deps = [":core_headers"], + deps = [ + ":config", + ":core_headers", + ], ) cc_test( @@ -635,7 +646,10 @@ cc_library( visibility = [ "//absl:__subpackages__", ], - deps = [":raw_logging_internal"], + deps = [ + ":config", + ":raw_logging_internal", + ], ) cc_test( diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index c521f32d..60fc1a83 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -21,6 +21,8 @@ absl_cc_library( atomic_hook HDRS "internal/atomic_hook.h" + DEPS + absl::config COPTS ${ABSL_DEFAULT_COPTS} ) @@ -148,6 +150,7 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS + absl::config absl::type_traits ) @@ -493,6 +496,7 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS + absl::config absl::core_headers ) @@ -518,6 +522,7 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS + absl::config absl::core_headers ) @@ -571,6 +576,7 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS + absl::config absl::raw_logging_internal ) diff --git a/absl/base/bit_cast_test.cc b/absl/base/bit_cast_test.cc index 4846add4..8a3a41ea 100644 --- a/absl/base/bit_cast_test.cc +++ b/absl/base/bit_cast_test.cc @@ -22,6 +22,7 @@ #include "absl/base/macros.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { template @@ -104,4 +105,5 @@ TEST(BitCast, Double) { } } // namespace +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/call_once.h b/absl/base/call_once.h index e1614e51..bc5ec937 100644 --- a/absl/base/call_once.h +++ b/absl/base/call_once.h @@ -41,6 +41,7 @@ #include "absl/base/port.h" namespace absl { +ABSL_NAMESPACE_BEGIN class once_flag; @@ -219,6 +220,7 @@ void call_once(absl::once_flag& flag, Callable&& fn, Args&&... args) { } } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_CALL_ONCE_H_ diff --git a/absl/base/call_once_test.cc b/absl/base/call_once_test.cc index 9a5a5c13..11d26c44 100644 --- a/absl/base/call_once_test.cc +++ b/absl/base/call_once_test.cc @@ -24,6 +24,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { absl::once_flag once; @@ -102,4 +103,5 @@ TEST(CallOnceTest, ExecutionCount) { } } // namespace +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/casts.h b/absl/base/casts.h index aba01782..322cc1d2 100644 --- a/absl/base/casts.h +++ b/absl/base/casts.h @@ -34,6 +34,7 @@ #include "absl/meta/type_traits.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace internal_casts { @@ -177,6 +178,7 @@ inline Dest bit_cast(const Source& source) { return dest; } +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_CASTS_H_ diff --git a/absl/base/config.h b/absl/base/config.h index 556b186c..87f5b4ae 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -66,6 +66,33 @@ #include "absl/base/options.h" #include "absl/base/policy_checks.h" +// ----------------------------------------------------------------------------- +// Abseil namespace annotations +// ----------------------------------------------------------------------------- + +// ABSL_NAMESPACE_BEGIN/ABSL_NAMESPACE_END +// +// An annotation placed at the beginning/end of each `namespace absl` scope. +// This is used to inject an inline namespace. +// +// The proper way to write Abseil code in the `absl` namespace is: +// +// namespace absl { +// ABSL_NAMESPACE_BEGIN +// +// void Foo(); // absl::Foo(). +// +// ABSL_NAMESPACE_END +// } // namespace absl +// +// Users of Abseil should not use these macros, because users of Abseil should +// not write `namespace absl {` in their own code for any reason. (Abseil does +// not support forward declarations of its own types, nor does it support +// user-provided specialization of Abseil templates. Code that violates these +// rules may be broken without warning.) +#define ABSL_NAMESPACE_BEGIN +#define ABSL_NAMESPACE_END + // ----------------------------------------------------------------------------- // Compiler Feature Checks // ----------------------------------------------------------------------------- diff --git a/absl/base/const_init.h b/absl/base/const_init.h index 17858a77..16520b61 100644 --- a/absl/base/const_init.h +++ b/absl/base/const_init.h @@ -22,6 +22,8 @@ #ifndef ABSL_BASE_CONST_INIT_H_ #define ABSL_BASE_CONST_INIT_H_ +#include "absl/base/config.h" + // In general, objects with static storage duration (such as global variables) // can trigger tricky object lifetime situations. Attempting to access them // from the constructors or destructors of other global objects can result in @@ -62,11 +64,13 @@ // or thread_local storage duration. namespace absl { +ABSL_NAMESPACE_BEGIN enum ConstInitType { kConstInit, }; +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_CONST_INIT_H_ diff --git a/absl/base/inline_variable_test.cc b/absl/base/inline_variable_test.cc index 471f7063..37a40e1e 100644 --- a/absl/base/inline_variable_test.cc +++ b/absl/base/inline_variable_test.cc @@ -20,6 +20,7 @@ #include "gtest/gtest.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace inline_variable_testing_internal { namespace { @@ -59,4 +60,5 @@ TEST(InlineVariableTest, FunPtrType) { } // namespace } // namespace inline_variable_testing_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/inline_variable_test_a.cc b/absl/base/inline_variable_test_a.cc index d0b8e7d3..f96a58d9 100644 --- a/absl/base/inline_variable_test_a.cc +++ b/absl/base/inline_variable_test_a.cc @@ -15,6 +15,7 @@ #include "absl/base/internal/inline_variable_testing.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace inline_variable_testing_internal { const Foo& get_foo_a() { return inline_variable_foo; } @@ -22,4 +23,5 @@ const Foo& get_foo_a() { return inline_variable_foo; } const int& get_int_a() { return inline_variable_int; } } // namespace inline_variable_testing_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/inline_variable_test_b.cc b/absl/base/inline_variable_test_b.cc index 931d56d0..038adc30 100644 --- a/absl/base/inline_variable_test_b.cc +++ b/absl/base/inline_variable_test_b.cc @@ -15,6 +15,7 @@ #include "absl/base/internal/inline_variable_testing.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace inline_variable_testing_internal { const Foo& get_foo_b() { return inline_variable_foo; } @@ -22,4 +23,5 @@ const Foo& get_foo_b() { return inline_variable_foo; } const int& get_int_b() { return inline_variable_int; } } // namespace inline_variable_testing_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/atomic_hook.h b/absl/base/internal/atomic_hook.h index 6df956a6..d885bc05 100644 --- a/absl/base/internal/atomic_hook.h +++ b/absl/base/internal/atomic_hook.h @@ -20,6 +20,8 @@ #include #include +#include "absl/base/config.h" + #ifdef _MSC_FULL_VER #define ABSL_HAVE_WORKING_ATOMIC_POINTER 0 #define ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT 0 @@ -29,6 +31,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { template @@ -170,6 +173,7 @@ class AtomicHook { #undef ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ diff --git a/absl/base/internal/atomic_hook_test_helper.cc b/absl/base/internal/atomic_hook_test_helper.cc index fad7a89a..f95d962b 100644 --- a/absl/base/internal/atomic_hook_test_helper.cc +++ b/absl/base/internal/atomic_hook_test_helper.cc @@ -18,6 +18,7 @@ #include "absl/base/internal/atomic_hook.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace atomic_hook_internal { ABSL_CONST_INIT absl::base_internal::AtomicHook func(DefaultFunc); @@ -26,4 +27,5 @@ void DefaultFunc() { default_func_calls++; } void RegisterFunc(VoidF f) { func.Store(f); } } // namespace atomic_hook_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/atomic_hook_test_helper.h b/absl/base/internal/atomic_hook_test_helper.h index 44ff780d..3e72b497 100644 --- a/absl/base/internal/atomic_hook_test_helper.h +++ b/absl/base/internal/atomic_hook_test_helper.h @@ -18,6 +18,7 @@ #include "absl/base/internal/atomic_hook.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace atomic_hook_internal { using VoidF = void (*)(); @@ -27,6 +28,7 @@ void DefaultFunc(); void RegisterFunc(VoidF func); } // namespace atomic_hook_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_ATOMIC_HOOK_TEST_HELPER_H_ diff --git a/absl/base/internal/bits.h b/absl/base/internal/bits.h index 450b923f..8b03453c 100644 --- a/absl/base/internal/bits.h +++ b/absl/base/internal/bits.h @@ -20,6 +20,8 @@ #include +#include "absl/base/config.h" + // Clang on Windows has __builtin_clzll; otherwise we need to use the // windows intrinsic functions. #if defined(_MSC_VER) @@ -46,6 +48,7 @@ namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64Slow(uint64_t n) { @@ -209,6 +212,7 @@ ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32(uint32_t n) { #undef ABSL_BASE_INTERNAL_FORCEINLINE } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_BITS_H_ diff --git a/absl/base/internal/cycleclock.cc b/absl/base/internal/cycleclock.cc index e9844b71..0e65005b 100644 --- a/absl/base/internal/cycleclock.cc +++ b/absl/base/internal/cycleclock.cc @@ -28,6 +28,7 @@ #include "absl/base/internal/unscaledcycleclock.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { #if ABSL_USE_UNSCALED_CYCLECLOCK @@ -102,4 +103,5 @@ double CycleClock::Frequency() { #endif } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/cycleclock.h b/absl/base/internal/cycleclock.h index 794564e1..a18b5844 100644 --- a/absl/base/internal/cycleclock.h +++ b/absl/base/internal/cycleclock.h @@ -44,7 +44,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // ----------------------------------------------------------------------------- @@ -85,6 +88,7 @@ class CycleClockSource { }; } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_CYCLECLOCK_H_ diff --git a/absl/base/internal/direct_mmap.h b/absl/base/internal/direct_mmap.h index 0401ddfa..5618867b 100644 --- a/absl/base/internal/direct_mmap.h +++ b/absl/base/internal/direct_mmap.h @@ -62,6 +62,7 @@ extern "C" void* __mmap2(void*, size_t, int, int, int, size_t); #endif // __BIONIC__ namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // Platform specific logic extracted from @@ -128,6 +129,7 @@ inline int DirectMunmap(void* start, size_t length) { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #else // !__linux__ @@ -136,6 +138,7 @@ inline int DirectMunmap(void* start, size_t length) { // actual mmap()/munmap() methods. namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd, @@ -148,6 +151,7 @@ inline int DirectMunmap(void* start, size_t length) { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // __linux__ diff --git a/absl/base/internal/endian.h b/absl/base/internal/endian.h index 8233cb52..9677530e 100644 --- a/absl/base/internal/endian.h +++ b/absl/base/internal/endian.h @@ -31,6 +31,7 @@ #include "absl/base/port.h" namespace absl { +ABSL_NAMESPACE_BEGIN // Use compiler byte-swapping intrinsics if they are available. 32-bit // and 64-bit versions are available in Clang and GCC as of GCC 4.3.0. @@ -259,6 +260,7 @@ inline void Store64(void *p, uint64_t v) { } // namespace big_endian +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_ENDIAN_H_ diff --git a/absl/base/internal/endian_test.cc b/absl/base/internal/endian_test.cc index 98a099e4..aa6b8496 100644 --- a/absl/base/internal/endian_test.cc +++ b/absl/base/internal/endian_test.cc @@ -24,6 +24,7 @@ #include "absl/base/config.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace { const uint64_t kInitialNumber{0x0123456789abcdef}; @@ -260,4 +261,5 @@ TEST(EndianessTest, big_endian) { } } // namespace +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/exponential_biased.cc b/absl/base/internal/exponential_biased.cc index 7786c303..1b30c061 100644 --- a/absl/base/internal/exponential_biased.cc +++ b/absl/base/internal/exponential_biased.cc @@ -25,6 +25,7 @@ #include "absl/base/optimization.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // The algorithm generates a random number between 0 and 1 and applies the @@ -88,4 +89,5 @@ void ExponentialBiased::Initialize() { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/exponential_biased.h b/absl/base/internal/exponential_biased.h index 6701e695..94f79a33 100644 --- a/absl/base/internal/exponential_biased.h +++ b/absl/base/internal/exponential_biased.h @@ -17,9 +17,11 @@ #include +#include "absl/base/config.h" #include "absl/base/macros.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // ExponentialBiased provides a small and fast random number generator for a @@ -122,6 +124,7 @@ inline uint64_t ExponentialBiased::NextRandom(uint64_t rnd) { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_EXPONENTIAL_BIASED_H_ diff --git a/absl/base/internal/exponential_biased_test.cc b/absl/base/internal/exponential_biased_test.cc index af003239..90a482d2 100644 --- a/absl/base/internal/exponential_biased_test.cc +++ b/absl/base/internal/exponential_biased_test.cc @@ -27,6 +27,7 @@ using ::testing::Ge; namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { MATCHER_P2(IsBetween, a, b, @@ -194,4 +195,5 @@ TEST(ExponentialBiasedTest, InitializationModes) { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/hide_ptr.h b/absl/base/internal/hide_ptr.h index cf8f4080..1dba8090 100644 --- a/absl/base/internal/hide_ptr.h +++ b/absl/base/internal/hide_ptr.h @@ -17,7 +17,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // Arbitrary value with high bits set. Xor'ing with it is unlikely @@ -42,6 +45,7 @@ inline T* UnhidePtr(uintptr_t hidden) { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_HIDE_PTR_H_ diff --git a/absl/base/internal/identity.h b/absl/base/internal/identity.h index 086447c6..a3154ed7 100644 --- a/absl/base/internal/identity.h +++ b/absl/base/internal/identity.h @@ -16,7 +16,10 @@ #ifndef ABSL_BASE_INTERNAL_IDENTITY_H_ #define ABSL_BASE_INTERNAL_IDENTITY_H_ +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace internal { template @@ -28,6 +31,7 @@ template using identity_t = typename identity::type; } // namespace internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_IDENTITY_H_ diff --git a/absl/base/internal/inline_variable_testing.h b/absl/base/internal/inline_variable_testing.h index 15dc481e..3856b9f8 100644 --- a/absl/base/internal/inline_variable_testing.h +++ b/absl/base/internal/inline_variable_testing.h @@ -18,6 +18,7 @@ #include "absl/base/internal/inline_variable.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace inline_variable_testing_internal { struct Foo { @@ -39,6 +40,7 @@ const int& get_int_a(); const int& get_int_b(); } // namespace inline_variable_testing_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INLINE_VARIABLE_TESTING_H_ diff --git a/absl/base/internal/invoke.h b/absl/base/internal/invoke.h index 44f13302..c4eceebd 100644 --- a/absl/base/internal/invoke.h +++ b/absl/base/internal/invoke.h @@ -45,6 +45,7 @@ // top of this file for the API documentation. namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // The five classes below each implement one of the clauses from the definition @@ -180,6 +181,7 @@ InvokeT Invoke(F&& f, Args&&... args) { std::forward(args)...); } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_INVOKE_H_ diff --git a/absl/base/internal/low_level_alloc.cc b/absl/base/internal/low_level_alloc.cc index a0638f9e..225abc24 100644 --- a/absl/base/internal/low_level_alloc.cc +++ b/absl/base/internal/low_level_alloc.cc @@ -63,6 +63,7 @@ #endif // __APPLE__ namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // A first-fit allocator with amortized logarithmic free() time. @@ -612,6 +613,7 @@ void *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_LOW_LEVEL_ALLOC_MISSING diff --git a/absl/base/internal/low_level_alloc.h b/absl/base/internal/low_level_alloc.h index c98cdb30..db91951c 100644 --- a/absl/base/internal/low_level_alloc.h +++ b/absl/base/internal/low_level_alloc.h @@ -55,6 +55,7 @@ #include "absl/base/port.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { class LowLevelAlloc { @@ -119,6 +120,7 @@ class LowLevelAlloc { }; } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ diff --git a/absl/base/internal/low_level_alloc_test.cc b/absl/base/internal/low_level_alloc_test.cc index 34a080cb..7abbbf9c 100644 --- a/absl/base/internal/low_level_alloc_test.cc +++ b/absl/base/internal/low_level_alloc_test.cc @@ -22,6 +22,7 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { namespace { @@ -149,6 +150,7 @@ static struct BeforeMain { } // namespace } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl int main(int argc, char *argv[]) { diff --git a/absl/base/internal/low_level_scheduling.h b/absl/base/internal/low_level_scheduling.h index 0fcc8d3b..961cc981 100644 --- a/absl/base/internal/low_level_scheduling.h +++ b/absl/base/internal/low_level_scheduling.h @@ -28,6 +28,7 @@ extern "C" bool __google_disable_rescheduling(void); extern "C" void __google_enable_rescheduling(bool disable_result); namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { class SchedulingHelper; // To allow use of SchedulingGuard. @@ -100,6 +101,7 @@ inline void SchedulingGuard::EnableRescheduling(bool /* disable_result */) { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ diff --git a/absl/base/internal/periodic_sampler.cc b/absl/base/internal/periodic_sampler.cc index 87c3c85a..520dabba 100644 --- a/absl/base/internal/periodic_sampler.cc +++ b/absl/base/internal/periodic_sampler.cc @@ -19,6 +19,7 @@ #include "absl/base/internal/exponential_biased.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { int64_t PeriodicSamplerBase::GetExponentialBiased(int period) noexcept { @@ -48,4 +49,5 @@ bool PeriodicSamplerBase::SubtleConfirmSample() noexcept { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/periodic_sampler.h b/absl/base/internal/periodic_sampler.h index 23879742..f8a86796 100644 --- a/absl/base/internal/periodic_sampler.h +++ b/absl/base/internal/periodic_sampler.h @@ -23,6 +23,7 @@ #include "absl/base/optimization.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // PeriodicSamplerBase provides the basic period sampler implementation. @@ -204,6 +205,7 @@ template std::atomic PeriodicSampler::period_(default_period); } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_PERIODIC_SAMPLER_H_ diff --git a/absl/base/internal/periodic_sampler_benchmark.cc b/absl/base/internal/periodic_sampler_benchmark.cc index 03759632..5ad469ce 100644 --- a/absl/base/internal/periodic_sampler_benchmark.cc +++ b/absl/base/internal/periodic_sampler_benchmark.cc @@ -16,6 +16,7 @@ #include "absl/base/internal/periodic_sampler.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { namespace { @@ -74,4 +75,5 @@ BENCHMARK(BM_PeriodicSampler_Disabled); } // namespace } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/periodic_sampler_test.cc b/absl/base/internal/periodic_sampler_test.cc index 29f4d24d..3b301e37 100644 --- a/absl/base/internal/periodic_sampler_test.cc +++ b/absl/base/internal/periodic_sampler_test.cc @@ -22,6 +22,7 @@ #include "absl/base/macros.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { namespace { @@ -172,4 +173,5 @@ TEST(PeriodicSamplerTest, SetGlobalPeriod) { } // namespace } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc index d20bf34e..d79c5486 100644 --- a/absl/base/internal/raw_logging.cc +++ b/absl/base/internal/raw_logging.cc @@ -182,6 +182,7 @@ void RawLogVA(absl::LogSeverity severity, const char* file, int line, } // namespace namespace absl { +ABSL_NAMESPACE_BEGIN namespace raw_logging_internal { void SafeWriteToStderr(const char *s, size_t len) { #if defined(ABSL_HAVE_SYSCALL_WRITE) @@ -232,4 +233,5 @@ void RegisterInternalLogFunction(InternalLogFunction func) { } } // namespace raw_logging_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h index 49c8dfbf..12145c48 100644 --- a/absl/base/internal/raw_logging.h +++ b/absl/base/internal/raw_logging.h @@ -93,6 +93,7 @@ ::absl::NormalizeLogSeverity(severity) namespace absl { +ABSL_NAMESPACE_BEGIN namespace raw_logging_internal { // Helper function to implement ABSL_RAW_LOG @@ -172,6 +173,7 @@ extern base_internal::AtomicHook internal_log_function; void RegisterInternalLogFunction(InternalLogFunction func); } // namespace raw_logging_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_RAW_LOGGING_H_ diff --git a/absl/base/internal/scheduling_mode.h b/absl/base/internal/scheduling_mode.h index d5b4b7fd..8be5ab6d 100644 --- a/absl/base/internal/scheduling_mode.h +++ b/absl/base/internal/scheduling_mode.h @@ -18,7 +18,10 @@ #ifndef ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ #define ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // Used to describe how a thread may be scheduled. Typically associated with @@ -49,6 +52,7 @@ enum SchedulingMode { }; } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ diff --git a/absl/base/internal/scoped_set_env.cc b/absl/base/internal/scoped_set_env.cc index 3ac3f68d..8a934cb5 100644 --- a/absl/base/internal/scoped_set_env.cc +++ b/absl/base/internal/scoped_set_env.cc @@ -23,6 +23,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { namespace { @@ -76,4 +77,5 @@ ScopedSetEnv::~ScopedSetEnv() { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/scoped_set_env.h b/absl/base/internal/scoped_set_env.h index 855b22fd..19ec7b5d 100644 --- a/absl/base/internal/scoped_set_env.h +++ b/absl/base/internal/scoped_set_env.h @@ -19,7 +19,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { class ScopedSetEnv { @@ -36,6 +39,7 @@ class ScopedSetEnv { }; } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_SCOPED_SET_ENV_H_ diff --git a/absl/base/internal/spinlock.cc b/absl/base/internal/spinlock.cc index 7354438f..8dd8dab9 100644 --- a/absl/base/internal/spinlock.cc +++ b/absl/base/internal/spinlock.cc @@ -54,6 +54,7 @@ // holder to acquire the lock. There may be outstanding waiter(s). namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { ABSL_CONST_INIT static base_internal::AtomicHook *w, uint32_t value, int loop, int SpinLockSuggestedDelayNS(int loop); } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl // In some build configurations we pass --detect-odr-violations to the diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc index 68d4266b..7945322f 100644 --- a/absl/base/internal/sysinfo.cc +++ b/absl/base/internal/sysinfo.cc @@ -55,6 +55,7 @@ #include "absl/base/internal/unscaledcycleclock.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { static once_flag init_system_info_once; @@ -409,4 +410,5 @@ pid_t GetTID() { #endif } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/sysinfo.h b/absl/base/internal/sysinfo.h index 93356d80..7246d5dd 100644 --- a/absl/base/internal/sysinfo.h +++ b/absl/base/internal/sysinfo.h @@ -33,6 +33,7 @@ #include "absl/base/port.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // Nominal core processor cycles per second of each processor. This is _not_ @@ -59,6 +60,7 @@ using pid_t = uint32_t; pid_t GetTID(); } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_SYSINFO_H_ diff --git a/absl/base/internal/sysinfo_test.cc b/absl/base/internal/sysinfo_test.cc index 82bbcc2b..cdec9b6a 100644 --- a/absl/base/internal/sysinfo_test.cc +++ b/absl/base/internal/sysinfo_test.cc @@ -28,6 +28,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { namespace { @@ -95,4 +96,5 @@ TEST(SysinfoTest, LinuxGetTID) { } // namespace } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/thread_identity.cc b/absl/base/internal/thread_identity.cc index 0ea159c5..6a28f246 100644 --- a/absl/base/internal/thread_identity.cc +++ b/absl/base/internal/thread_identity.cc @@ -28,6 +28,7 @@ #include "absl/base/internal/spinlock.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { #if ABSL_THREAD_IDENTITY_MODE != ABSL_THREAD_IDENTITY_MODE_USE_CPP11 @@ -135,4 +136,5 @@ ThreadIdentity* CurrentThreadIdentityIfPresent() { #endif } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/thread_identity.h b/absl/base/internal/thread_identity.h index 7cbce9cc..a1aa45ff 100644 --- a/absl/base/internal/thread_identity.h +++ b/absl/base/internal/thread_identity.h @@ -33,6 +33,7 @@ #include "absl/base/internal/per_thread_tls.h" namespace absl { +ABSL_NAMESPACE_BEGIN struct SynchLocksHeld; struct SynchWaitParams; @@ -243,6 +244,7 @@ inline ThreadIdentity* CurrentThreadIdentityIfPresent() { #endif } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ diff --git a/absl/base/internal/thread_identity_test.cc b/absl/base/internal/thread_identity_test.cc index 13bfbe3b..3685779c 100644 --- a/absl/base/internal/thread_identity_test.cc +++ b/absl/base/internal/thread_identity_test.cc @@ -25,6 +25,7 @@ #include "absl/synchronization/mutex.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { namespace { @@ -123,4 +124,5 @@ TEST(ThreadIdentityTest, ReusedThreadIdentityMutexTest) { } // namespace } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/throw_delegate.cc b/absl/base/internal/throw_delegate.cc index 8e928b8a..c055f75d 100644 --- a/absl/base/internal/throw_delegate.cc +++ b/absl/base/internal/throw_delegate.cc @@ -22,6 +22,7 @@ #include "absl/base/internal/raw_logging.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { namespace { @@ -103,4 +104,5 @@ void ThrowStdBadFunctionCall() { Throw(std::bad_function_call()); } void ThrowStdBadAlloc() { Throw(std::bad_alloc()); } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/internal/throw_delegate.h b/absl/base/internal/throw_delegate.h index 03c700b5..075f5272 100644 --- a/absl/base/internal/throw_delegate.h +++ b/absl/base/internal/throw_delegate.h @@ -19,7 +19,10 @@ #include +#include "absl/base/config.h" + namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // Helper functions that allow throwing exceptions consistently from anywhere. @@ -66,6 +69,7 @@ namespace base_internal { // [[noreturn]] void ThrowStdBadArrayNewLength(); } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ diff --git a/absl/base/internal/unaligned_access.h b/absl/base/internal/unaligned_access.h index 2cf7c1d4..6be56c86 100644 --- a/absl/base/internal/unaligned_access.h +++ b/absl/base/internal/unaligned_access.h @@ -18,9 +18,11 @@ #define ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_ #include + #include #include "absl/base/attributes.h" +#include "absl/base/config.h" // unaligned APIs @@ -56,6 +58,7 @@ void __sanitizer_unaligned_store64(void *p, uint64_t v); } // extern "C" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { inline uint16_t UnalignedLoad16(const void *p) { @@ -83,6 +86,7 @@ inline void UnalignedStore64(void *p, uint64_t v) { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ @@ -102,6 +106,7 @@ inline void UnalignedStore64(void *p, uint64_t v) { #else namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { inline uint16_t UnalignedLoad16(const void *p) { @@ -129,6 +134,7 @@ inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); } inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ diff --git a/absl/base/internal/unscaledcycleclock.cc b/absl/base/internal/unscaledcycleclock.cc index 593762bc..a32936ae 100644 --- a/absl/base/internal/unscaledcycleclock.cc +++ b/absl/base/internal/unscaledcycleclock.cc @@ -27,6 +27,7 @@ #include "absl/base/internal/sysinfo.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { #if defined(__i386__) @@ -96,6 +97,7 @@ double UnscaledCycleClock::Frequency() { #endif } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USE_UNSCALED_CYCLECLOCK diff --git a/absl/base/internal/unscaledcycleclock.h b/absl/base/internal/unscaledcycleclock.h index 2d361e96..cdce9bf8 100644 --- a/absl/base/internal/unscaledcycleclock.h +++ b/absl/base/internal/unscaledcycleclock.h @@ -86,6 +86,7 @@ #endif namespace absl { +ABSL_NAMESPACE_BEGIN namespace time_internal { class UnscaledCycleClockWrapperForGetCurrentTime; } // namespace time_internal @@ -115,6 +116,7 @@ class UnscaledCycleClock { }; } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_USE_UNSCALED_CYCLECLOCK diff --git a/absl/base/invoke_test.cc b/absl/base/invoke_test.cc index 9074443b..6aa613c9 100644 --- a/absl/base/invoke_test.cc +++ b/absl/base/invoke_test.cc @@ -25,6 +25,7 @@ #include "absl/strings/str_cat.h" namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { namespace { @@ -218,4 +219,5 @@ TEST(InvokeTest, SfinaeFriendly) { } // namespace } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/log_severity.cc b/absl/base/log_severity.cc index 02a2a485..72312afd 100644 --- a/absl/base/log_severity.cc +++ b/absl/base/log_severity.cc @@ -17,9 +17,11 @@ #include namespace absl { +ABSL_NAMESPACE_BEGIN std::ostream& operator<<(std::ostream& os, absl::LogSeverity s) { if (s == absl::NormalizeLogSeverity(s)) return os << absl::LogSeverityName(s); return os << "absl::LogSeverity(" << static_cast(s) << ")"; } +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/log_severity.h b/absl/base/log_severity.h index f5dc7d26..e247c4a9 100644 --- a/absl/base/log_severity.h +++ b/absl/base/log_severity.h @@ -19,8 +19,10 @@ #include #include "absl/base/attributes.h" +#include "absl/base/config.h" namespace absl { +ABSL_NAMESPACE_BEGIN // Four severity levels are defined. Logging APIs should terminate the program // when a message is logged at severity `kFatal`; the other levels have no @@ -79,6 +81,7 @@ constexpr absl::LogSeverity NormalizeLogSeverity(int s) { // unspecified; do not rely on it. std::ostream& operator<<(std::ostream& os, absl::LogSeverity s); +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ diff --git a/absl/base/macros.h b/absl/base/macros.h index d414dcac..7565f022 100644 --- a/absl/base/macros.h +++ b/absl/base/macros.h @@ -44,12 +44,14 @@ (sizeof(::absl::macros_internal::ArraySizeHelper(array))) namespace absl { +ABSL_NAMESPACE_BEGIN namespace macros_internal { // Note: this internal template function declaration is used by ABSL_ARRAYSIZE. // The function doesn't need a definition, as we only use its type. template auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N]; } // namespace macros_internal +ABSL_NAMESPACE_END } // namespace absl // kLinkerInitialized @@ -73,11 +75,13 @@ auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N]; // // Invocation // static MyClass my_global(absl::base_internal::kLinkerInitialized); namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { enum LinkerInitialized { kLinkerInitialized = 0, }; } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl // ABSL_FALLTHROUGH_INTENDED diff --git a/absl/base/spinlock_test_common.cc b/absl/base/spinlock_test_common.cc index 84fc4dac..08f61ba8 100644 --- a/absl/base/spinlock_test_common.cc +++ b/absl/base/spinlock_test_common.cc @@ -36,6 +36,7 @@ constexpr int32_t kNumThreads = 10; constexpr int32_t kIters = 1000; namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // This is defined outside of anonymous namespace so that it can be @@ -266,4 +267,5 @@ TEST(SpinLockWithThreads, DoesNotDeadlock) { } // namespace } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/base/thread_annotations.h b/absl/base/thread_annotations.h index f98af9f9..5f51c0c2 100644 --- a/absl/base/thread_annotations.h +++ b/absl/base/thread_annotations.h @@ -34,6 +34,7 @@ #ifndef ABSL_BASE_THREAD_ANNOTATIONS_H_ #define ABSL_BASE_THREAD_ANNOTATIONS_H_ +#include "absl/base/config.h" // TODO(mbonadei): Remove after the backward compatibility period. #include "absl/base/internal/thread_annotations.h" // IWYU pragma: export @@ -256,6 +257,7 @@ #define ABSL_TS_UNCHECKED_READ(x) absl::base_internal::ts_unchecked_read(x) namespace absl { +ABSL_NAMESPACE_BEGIN namespace base_internal { // Takes a reference to a guarded data member, and returns an unguarded @@ -272,6 +274,7 @@ inline T& ts_unchecked_read(T& v) ABSL_NO_THREAD_SAFETY_ANALYSIS { } } // namespace base_internal +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_BASE_THREAD_ANNOTATIONS_H_ diff --git a/absl/flags/internal/usage.cc b/absl/flags/internal/usage.cc index 181c35c6..dc12e32f 100644 --- a/absl/flags/internal/usage.cc +++ b/absl/flags/internal/usage.cc @@ -200,7 +200,7 @@ void FlagHelpHumanReadable(const flags_internal::CommandLineFlag& flag, FlagHelpPrettyPrinter printer(80, out); // Max line length is 80. // Flag name. - printer.Write(absl::StrCat("-", flag.Name())); + printer.Write(absl::StrCat("--", flag.Name())); // Flag help. printer.Write(absl::StrCat("(", flag.Help(), ");"), /*wrap_line=*/true); diff --git a/absl/flags/internal/usage_test.cc b/absl/flags/internal/usage_test.cc index d15e4484..1e9ffdf7 100644 --- a/absl/flags/internal/usage_test.cc +++ b/absl/flags/internal/usage_test.cc @@ -111,7 +111,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_01) { flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); EXPECT_EQ( test_buf.str(), - R"( -usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); + R"( --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); default: 101; )"); } @@ -123,7 +123,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_02) { flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); EXPECT_EQ( test_buf.str(), - R"( -usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); + R"( --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); default: false; )"); } @@ -135,7 +135,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_03) { flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); EXPECT_EQ( test_buf.str(), - R"( -usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); + R"( --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); default: 1.03; )"); } @@ -147,7 +147,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_04) { flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); EXPECT_EQ( test_buf.str(), - R"( -usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); + R"( --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); default: 1000000000000004; )"); } @@ -159,7 +159,7 @@ TEST_F(UsageReportingTest, TestFlagHelpHRF_on_flag_05) { flags::FlagHelp(test_buf, *flag, flags::HelpFormat::kHumanReadable); EXPECT_EQ( test_buf.str(), - R"( -usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); + R"( --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); default: UDT{}; )"); } @@ -171,17 +171,17 @@ TEST_F(UsageReportingTest, TestFlagsHelpHRF) { R"(usage_test: Custom usage message Flags from absl/flags/internal/usage_test.cc: - -usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); + --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); default: 101; - -usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); + --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); default: false; - -usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); + --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); default: 1.03; - -usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); + --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); default: 1000000000000004; - -usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); + --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); default: UDT{}; - -usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. + --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. Some more help. Even more long long long long long long long long long long long long help @@ -247,17 +247,17 @@ TEST_F(UsageReportingTest, TestUsageFlag_helpshort) { R"(usage_test: Custom usage message Flags from absl/flags/internal/usage_test.cc: - -usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); + --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); default: 101; - -usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); + --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); default: false; - -usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); + --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); default: 1.03; - -usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); + --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); default: 1000000000000004; - -usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); + --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); default: UDT{}; - -usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. + --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. Some more help. Even more long long long long long long long long long long long long help @@ -276,17 +276,17 @@ TEST_F(UsageReportingTest, TestUsageFlag_help) { R"(usage_test: Custom usage message Flags from absl/flags/internal/usage_test.cc: - -usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); + --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); default: 101; - -usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); + --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); default: false; - -usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); + --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); default: 1.03; - -usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); + --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); default: 1000000000000004; - -usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); + --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); default: UDT{}; - -usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. + --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. Some more help. Even more long long long long long long long long long long long long help @@ -307,17 +307,17 @@ TEST_F(UsageReportingTest, TestUsageFlag_helppackage) { R"(usage_test: Custom usage message Flags from absl/flags/internal/usage_test.cc: - -usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); + --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); default: 101; - -usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); + --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); default: false; - -usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); + --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); default: 1.03; - -usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); + --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); default: 1000000000000004; - -usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); + --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); default: UDT{}; - -usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. + --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. Some more help. Even more long long long long long long long long long long long long help @@ -372,17 +372,17 @@ TEST_F(UsageReportingTest, TestUsageFlag_helpon) { R"(usage_test: Custom usage message Flags from absl/flags/internal/usage_test.cc: - -usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); + --usage_reporting_test_flag_01 (usage_reporting_test_flag_01 help message); default: 101; - -usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); + --usage_reporting_test_flag_02 (usage_reporting_test_flag_02 help message); default: false; - -usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); + --usage_reporting_test_flag_03 (usage_reporting_test_flag_03 help message); default: 1.03; - -usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); + --usage_reporting_test_flag_04 (usage_reporting_test_flag_04 help message); default: 1000000000000004; - -usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); + --usage_reporting_test_flag_05 (usage_reporting_test_flag_05 help message); default: UDT{}; - -usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. + --usage_reporting_test_flag_06 (usage_reporting_test_flag_06 help message. Some more help. Even more long long long long long long long long long long long long help diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h index 79416cc8..a209a927 100644 --- a/absl/strings/internal/str_format/arg.h +++ b/absl/strings/internal/str_format/arg.h @@ -18,8 +18,6 @@ #include "absl/strings/internal/str_format/extension.h" #include "absl/strings/string_view.h" -class CordReader; - namespace absl { class Cord; @@ -67,8 +65,7 @@ ConvertResult FormatConvertImpl(const char* v, FormatSinkImpl* sink); template ::value>::type* = nullptr, - class AbslCordReader = ::CordReader> + std::is_same::value>::type* = nullptr> ConvertResult FormatConvertImpl(const AbslCord& value, ConversionSpec conv, FormatSinkImpl* sink) { @@ -90,11 +87,17 @@ ConvertResult FormatConvertImpl(const AbslCord& value, if (space_remaining > 0 && !is_left) sink->Append(space_remaining, ' '); - string_view piece; - for (AbslCordReader reader(value); - to_write > 0 && reader.ReadFragment(&piece); to_write -= piece.size()) { - if (piece.size() > to_write) piece.remove_suffix(piece.size() - to_write); + for (string_view piece : value.Chunks()) { + if (piece.size() > to_write) { + piece.remove_suffix(piece.size() - to_write); + to_write = 0; + } else { + to_write -= piece.size(); + } sink->Append(piece); + if (to_write == 0) { + break; + } } if (space_remaining > 0 && is_left) sink->Append(space_remaining, ' '); diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h index 5e15ca40..7a0d6f50 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -54,18 +54,20 @@ namespace absl { // SimpleAtoi() // -// Converts the given string into an integer value, returning `true` if -// successful. The string must reflect a base-10 integer (optionally followed or -// preceded by ASCII whitespace) whose value falls within the range of the -// integer type. If any errors are encountered, this function returns `false`, -// leaving `out` in an unspecified state. +// Converts the given string (optionally followed or preceded by ASCII +// whitespace) into an integer value, returning `true` if successful. The string +// must reflect a base-10 integer whose value falls within the range of the +// integer type (optionally preceded by a `+` or `-`). If any errors are +// encountered, this function returns `false`, leaving `out` in an unspecified +// state. template ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str, int_type* out); // SimpleAtof() // // Converts the given string (optionally followed or preceded by ASCII -// whitespace) into a float, which may be rounded on overflow or underflow. +// whitespace) into a float, which may be rounded on overflow or underflow, +// returning `true` if successful. // See https://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`, except SimpleAtof() is locale-independent and will // always use the "C" locale. If any errors are encountered, this function @@ -75,7 +77,8 @@ ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* out); // SimpleAtod() // // Converts the given string (optionally followed or preceded by ASCII -// whitespace) into a double, which may be rounded on overflow or underflow. +// whitespace) into a double, which may be rounded on overflow or underflow, +// returning `true` if successful. // See https://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`, except SimpleAtod is locale-independent and will // always use the "C" locale. If any errors are encountered, this function -- cgit v1.2.3 From b3aaac8a37c467a1125c794196caa90d0957bdc3 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 9 Jan 2020 09:58:48 -0800 Subject: Export of internal Abseil changes -- 9beb68204986a015c9cb065b9fae4f9a8879a788 by Abseil Team : Move Base64EscapeInternal and CalculateBase64EscapedLenInternal to an internal header. PiperOrigin-RevId: 288917378 -- 90acfbe03b3f9f6de3ffa49c39343dfaa2c5d38c by Greg Falcon : Update macos CI script to support the ALTERNATE_OPTIONS environment variable. PiperOrigin-RevId: 288913564 -- f1572e870678cdcda6b48cb39780d1ad984e4c1b by Derek Mauro : Makes absl::NullSafeStringView constexpr Fixes https://github.com/abseil/abseil-cpp/issues/583 PiperOrigin-RevId: 288906940 -- d28a8471e32c10caa64bfffe6d6d4d0a8d144013 by Abseil Team : absl::GetFlag is lock free for small trivially copyable types. PiperOrigin-RevId: 288768172 -- 2643b8ed1a1dc836b38ab9e46538a1af129ffd67 by Gennadiy Rozental : Eliminate call to callback from flag initialization. We do not need to have this invocation inside FlagImpl::Init since SetCallback performs invocation anyways. Calling InitCallback from inside of Init complicates separation of value initialization from data guard initialization, which is about to happen. PiperOrigin-RevId: 288732526 -- 22caa880b7a4cb6da34e16a2e064a473c99e880b by Abseil Team : Fix the documentation on how to create a null string_view. PiperOrigin-RevId: 288727968 -- 10727c5cadc561837141176f4c9b9717cec9233a by Greg Falcon : Change CI scripts for gcc to use the ALTERNATE_OPTIONS file as well. PiperOrigin-RevId: 288718855 -- 5d1e2dd6c7fb12af8aa4337a0f61872f5f0c5992 by Greg Falcon : Add an option for using inline namespaces in Abseil. PiperOrigin-RevId: 288614491 GitOrigin-RevId: 9beb68204986a015c9cb065b9fae4f9a8879a788 Change-Id: If9acd46301e3df8cb231b4c16f7ed651bf4fb3c3 --- absl/base/config.h | 34 ++++++ absl/base/options.h | 26 +++++ absl/flags/config.h | 11 ++ absl/flags/flag.cc | 22 ---- absl/flags/flag.h | 45 +++++--- absl/flags/internal/commandlineflag.h | 32 +++--- absl/flags/internal/flag.cc | 15 ++- absl/flags/internal/flag.h | 95 +++++++++++++++-- absl/flags/parse.cc | 4 +- absl/strings/BUILD.bazel | 2 + absl/strings/CMakeLists.txt | 2 + absl/strings/escaping.cc | 188 +++------------------------------ absl/strings/internal/escaping.cc | 180 +++++++++++++++++++++++++++++++ absl/strings/internal/escaping.h | 58 ++++++++++ absl/strings/string_view.h | 4 +- absl/strings/string_view_test.cc | 25 +++++ ci/absl_types_options.h | 3 +- ci/linux_gcc-latest_libstdcxx_bazel.sh | 32 +++--- ci/macos_xcode_bazel.sh | 4 + 19 files changed, 527 insertions(+), 255 deletions(-) create mode 100644 absl/strings/internal/escaping.cc create mode 100644 absl/strings/internal/escaping.h (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index 87f5b4ae..edbf2246 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -90,8 +90,42 @@ // not support forward declarations of its own types, nor does it support // user-provided specialization of Abseil templates. Code that violates these // rules may be broken without warning.) +#if !defined(ABSL_OPTION_USE_INLINE_NAMESPACE) || \ + !defined(ABSL_OPTION_INLINE_NAMESPACE_NAME) +#error options.h is misconfigured. +#endif + +// Check that ABSL_OPTION_INLINE_NAMESPACE_NAME is neither "head" nor "" +#if defined(__cplusplus) && ABSL_OPTION_USE_INLINE_NAMESPACE == 1 + +#define ABSL_INTERNAL_DO_TOKEN_STR(x) #x +#define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x) +#define ABSL_INTERNAL_INLINE_NAMESPACE_STR \ + ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME) + +static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != '\0', + "options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must " + "not be empty."); +static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || + ABSL_INTERNAL_INLINE_NAMESPACE_STR[1] != 'e' || + ABSL_INTERNAL_INLINE_NAMESPACE_STR[2] != 'a' || + ABSL_INTERNAL_INLINE_NAMESPACE_STR[3] != 'd' || + ABSL_INTERNAL_INLINE_NAMESPACE_STR[4] != '\0', + "options.h misconfigured: ABSL_OPTION_INLINE_NAMESPACE_NAME must " + "be changed to a new, unique identifier name."); + +#endif + +#if ABSL_OPTION_USE_INLINE_NAMESPACE == 0 #define ABSL_NAMESPACE_BEGIN #define ABSL_NAMESPACE_END +#elif ABSL_OPTION_USE_INLINE_NAMESPACE == 1 +#define ABSL_NAMESPACE_BEGIN \ + inline namespace ABSL_OPTION_INLINE_NAMESPACE_NAME { +#define ABSL_NAMESPACE_END } +#else +#error options.h is misconfigured. +#endif // ----------------------------------------------------------------------------- // Compiler Feature Checks diff --git a/absl/base/options.h b/absl/base/options.h index 3961e63f..592b33b7 100644 --- a/absl/base/options.h +++ b/absl/base/options.h @@ -185,4 +185,30 @@ #define ABSL_OPTION_USE_STD_VARIANT 2 + +// ABSL_OPTION_USE_INLINE_NAMESPACE +// ABSL_OPTION_INLINE_NAMESPACE_NAME +// +// These options controls whether all entities in the absl namespace are +// contained within an inner inline namespace. This does not affect the +// user-visible API of Abseil, but it changes the mangled names of all symbols. +// +// This can be useful as a version tag if you are distributing Abseil in +// precompiled form. This will prevent a binary library build of Abseil with +// one inline namespace being used with headers configured with a different +// inline namespace name. Binary packagers are reminded that Abseil does not +// guarantee any ABI stability in Abseil, so any update of Abseil or +// configuration change in such a binary package should be combined with a +// new, unique value for the inline namespace name. +// +// A value of 0 means not to use inline namespaces. +// +// A value of 1 means to use an inline namespace with the given name inside +// namespace absl. If this is set, ABSL_OPTION_INLINE_NAMESPACE_NAME must also +// be changed to a new, unique identifier name. In particular "head" is not +// allowed. + +#define ABSL_OPTION_USE_INLINE_NAMESPACE 0 +#define ABSL_OPTION_INLINE_NAMESPACE_NAME head + #endif // ABSL_BASE_OPTIONS_H_ diff --git a/absl/flags/config.h b/absl/flags/config.h index a9fd97ad..fbe34961 100644 --- a/absl/flags/config.h +++ b/absl/flags/config.h @@ -45,4 +45,15 @@ #define ABSL_FLAGS_STRIP_HELP ABSL_FLAGS_STRIP_NAMES #endif +// ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD macro is used for using atomics with +// double words, e.g. absl::Duration. +// For reasons in bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878, modern +// versions of GCC do not support cmpxchg16b instruction in standard atomics. +#ifdef ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD +#error "ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD should not be defined." +#elif defined(__clang__) && defined(__x86_64__) && \ + defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) +#define ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD 1 +#endif + #endif // ABSL_FLAGS_CONFIG_H_ diff --git a/absl/flags/flag.cc b/absl/flags/flag.cc index 7faa7ade..491a66bc 100644 --- a/absl/flags/flag.cc +++ b/absl/flags/flag.cc @@ -20,28 +20,6 @@ namespace absl { ABSL_NAMESPACE_BEGIN -// We want to validate the type mismatch between type definition and -// declaration. The lock-free implementation does not allow us to do it, -// so in debug builds we always use the slower implementation, which always -// validates the type. -#ifndef NDEBUG -#define ABSL_FLAGS_ATOMIC_GET(T) \ - T GetFlag(const absl::Flag& flag) { return flag.Get(); } -#else -#define ABSL_FLAGS_ATOMIC_GET(T) \ - T GetFlag(const absl::Flag& flag) { \ - T result; \ - if (flag.AtomicGet(&result)) { \ - return result; \ - } \ - return flag.Get(); \ - } -#endif - -ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(ABSL_FLAGS_ATOMIC_GET) - -#undef ABSL_FLAGS_ATOMIC_GET - // This global nutex protects on-demand construction of flag objects in MSVC // builds. #if defined(_MSC_VER) && !defined(__clang__) diff --git a/absl/flags/flag.h b/absl/flags/flag.h index 326fb8ee..62e73f84 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -29,6 +29,8 @@ #ifndef ABSL_FLAGS_FLAG_H_ #define ABSL_FLAGS_FLAG_H_ +#include + #include "absl/base/attributes.h" #include "absl/base/casts.h" #include "absl/flags/config.h" @@ -181,23 +183,42 @@ class Flag { // // // FLAGS_firstname is a Flag of type `std::string` // std::string first_name = absl::GetFlag(FLAGS_firstname); -template +template ::value, int>::type = 0> ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag) { -#define ABSL_FLAGS_INTERNAL_LOCK_FREE_VALIDATE(BIT) \ - static_assert( \ - !std::is_same::value, \ - "Do not specify explicit template parameters to absl::GetFlag"); - ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(ABSL_FLAGS_INTERNAL_LOCK_FREE_VALIDATE) -#undef ABSL_FLAGS_INTERNAL_LOCK_FREE_VALIDATE - return flag.Get(); } +// We want to validate the type mismatch between type definition and +// declaration. The lock-free implementation does not allow us to do it, +// so in debug builds we always use the slower implementation, which always +// validates the type. +#ifndef NDEBUG +template ::value, int>::type = 0> +ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag) { + return flag.Get(); +} +#else // Overload for `GetFlag()` for types that support lock-free reads. -#define ABSL_FLAGS_INTERNAL_LOCK_FREE_EXPORT(T) \ - ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag); -ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(ABSL_FLAGS_INTERNAL_LOCK_FREE_EXPORT) -#undef ABSL_FLAGS_INTERNAL_LOCK_FREE_EXPORT +template ::value, int>::type = 0> +ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag) { + // T might not be default constructible. + union U { + T value; + U() {} + }; + U result; + if (flag.AtomicGet(&result.value)) { + return result.value; + } + return flag.Get(); +} +#endif // SetFlag() // diff --git a/absl/flags/internal/commandlineflag.h b/absl/flags/internal/commandlineflag.h index a0c18e80..1862306d 100644 --- a/absl/flags/internal/commandlineflag.h +++ b/absl/flags/internal/commandlineflag.h @@ -259,22 +259,22 @@ class CommandLineFlag { virtual void Read(void* dst) const = 0; }; -// This macro is the "source of truth" for the list of supported flag types we -// expect to perform lock free operations on. Specifically it generates code, -// a one argument macro operating on a type, supplied as a macro argument, for -// each type in the list. -#define ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(A) \ - A(bool) \ - A(short) \ - A(unsigned short) \ - A(int) \ - A(unsigned int) \ - A(long) \ - A(unsigned long) \ - A(long long) \ - A(unsigned long long) \ - A(double) \ - A(float) +// This macro is the "source of truth" for the list of supported flag built-in +// types. +#define ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A) \ + A(bool) \ + A(short) \ + A(unsigned short) \ + A(int) \ + A(unsigned int) \ + A(long) \ + A(unsigned long) \ + A(long long) \ + A(unsigned long long) \ + A(double) \ + A(float) \ + A(std::string) \ + A(std::vector) } // namespace flags_internal ABSL_NAMESPACE_END diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc index bb9a98f3..6979dc46 100644 --- a/absl/flags/internal/flag.cc +++ b/absl/flags/internal/flag.cc @@ -16,6 +16,7 @@ #include "absl/flags/internal/flag.h" #include "absl/base/optimization.h" +#include "absl/flags/config.h" #include "absl/flags/usage_config.h" #include "absl/synchronization/mutex.h" @@ -35,9 +36,7 @@ namespace { bool ShouldValidateFlagValue(FlagOpFn flag_type_id) { #define DONT_VALIDATE(T) \ if (flag_type_id == &flags_internal::FlagOps) return false; - ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(DONT_VALIDATE) - DONT_VALIDATE(std::string) - DONT_VALIDATE(std::vector) + ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(DONT_VALIDATE) #undef DONT_VALIDATE return true; @@ -85,7 +84,6 @@ void FlagImpl::Init() { cur_ = MakeInitValue().release(); StoreAtomic(); inited_.store(true, std::memory_order_release); - InvokeCallback(); } } @@ -264,8 +262,15 @@ void FlagImpl::StoreAtomic() { if (data_size <= sizeof(int64_t)) { int64_t t = 0; std::memcpy(&t, cur_, data_size); - atomic_.store(t, std::memory_order_release); + atomics_.small_atomic.store(t, std::memory_order_release); } +#if defined(ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD) + else if (data_size <= sizeof(FlagsInternalTwoWordsType)) { + FlagsInternalTwoWordsType t{0, 0}; + std::memcpy(&t, cur_, data_size); + atomics_.big_atomic.store(t, std::memory_order_release); + } +#endif } void FlagImpl::Write(const void* src, const flags_internal::FlagOpFn src_op) { diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index 7d5271c4..a5edfd17 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -20,6 +20,7 @@ #include #include "absl/base/thread_annotations.h" +#include "absl/flags/config.h" #include "absl/flags/internal/commandlineflag.h" #include "absl/flags/internal/registry.h" #include "absl/memory/memory.h" @@ -30,7 +31,61 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace flags_internal { -constexpr int64_t AtomicInit() { return 0xababababababababll; } +// The minimum atomic size we believe to generate lock free code, i.e. all +// trivially copyable types not bigger this size generate lock free code. +static constexpr int kMinLockFreeAtomicSize = 8; + +// The same as kMinLockFreeAtomicSize but maximum atomic size. As double words +// might use two registers, we want to dispatch the logic for them. +#if defined(ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD) +static constexpr int kMaxLockFreeAtomicSize = 16; +#else +static constexpr int kMaxLockFreeAtomicSize = 8; +#endif + +// We can use atomic in cases when it fits in the register, trivially copyable +// in order to make memcpy operations. +template +struct IsAtomicFlagTypeTrait { + static constexpr bool value = + (sizeof(T) <= kMaxLockFreeAtomicSize && + type_traits_internal::is_trivially_copyable::value); +}; + +// Clang does not always produce cmpxchg16b instruction when alignment of a 16 +// bytes type is not 16. +struct alignas(16) FlagsInternalTwoWordsType { + int64_t first; + int64_t second; +}; + +constexpr bool operator==(const FlagsInternalTwoWordsType& that, + const FlagsInternalTwoWordsType& other) { + return that.first == other.first && that.second == other.second; +} +constexpr bool operator!=(const FlagsInternalTwoWordsType& that, + const FlagsInternalTwoWordsType& other) { + return !(that == other); +} + +constexpr int64_t SmallAtomicInit() { return 0xababababababababll; } + +template +struct BestAtomicType { + using type = int64_t; + static constexpr int64_t AtomicInit() { return SmallAtomicInit(); } +}; + +template +struct BestAtomicType< + T, typename std::enable_if<(kMinLockFreeAtomicSize < sizeof(T) && + sizeof(T) <= kMaxLockFreeAtomicSize), + void>::type> { + using type = FlagsInternalTwoWordsType; + static constexpr FlagsInternalTwoWordsType AtomicInit() { + return {SmallAtomicInit(), SmallAtomicInit()}; + } +}; template class Flag; @@ -182,14 +237,15 @@ class FlagImpl { // it replaces `dst` with the new value. bool TryParse(void** dst, absl::string_view value, std::string* err) const ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()); + template bool AtomicGet(T* v) const { - const int64_t r = atomic_.load(std::memory_order_acquire); - if (r != flags_internal::AtomicInit()) { - std::memcpy(v, &r, sizeof(T)); + using U = flags_internal::BestAtomicType; + const typename U::type r = atomics_.template load(); + if (r != U::AtomicInit()) { + std::memcpy(static_cast(v), &r, sizeof(T)); return true; } - return false; } @@ -271,7 +327,34 @@ class FlagImpl { int64_t counter_ ABSL_GUARDED_BY(*DataGuard()) = 0; // For some types, a copy of the current value is kept in an atomically // accessible field. - std::atomic atomic_{flags_internal::AtomicInit()}; + union Atomics { + // Using small atomic for small types. + std::atomic small_atomic; + template ::type> + int64_t load() const { + return small_atomic.load(std::memory_order_acquire); + } + +#if defined(ABSL_FLAGS_INTERNAL_ATOMIC_DOUBLE_WORD) + // Using big atomics for big types. + std::atomic big_atomic; + template ::type> + FlagsInternalTwoWordsType load() const { + return big_atomic.load(std::memory_order_acquire); + } + constexpr Atomics() + : big_atomic{FlagsInternalTwoWordsType{SmallAtomicInit(), + SmallAtomicInit()}} {} +#else + constexpr Atomics() : small_atomic{SmallAtomicInit()} {} +#endif + }; + Atomics atomics_{}; struct CallbackData { FlagCallback func; diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc index 2f07725f..a288ace8 100644 --- a/absl/flags/parse.cc +++ b/absl/flags/parse.cc @@ -280,9 +280,7 @@ void CheckDefaultValuesParsingRoundtrip() { #define IGNORE_TYPE(T) \ if (flag->IsOfType()) return; - ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(IGNORE_TYPE) - IGNORE_TYPE(std::string) - IGNORE_TYPE(std::vector) + ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(IGNORE_TYPE) #undef IGNORE_TYPE flag->CheckDefaultValueParsingRoundtrip(); diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index 8d0a6b6d..dc7e1bfd 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -37,6 +37,7 @@ cc_library( "internal/charconv_bigint.h", "internal/charconv_parse.cc", "internal/charconv_parse.h", + "internal/escaping.cc", "internal/memutil.cc", "internal/memutil.h", "internal/stl_type_traits.h", @@ -54,6 +55,7 @@ cc_library( "ascii.h", "charconv.h", "escaping.h", + "internal/escaping.h", "match.h", "numbers.h", "str_cat.h", diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index 98101573..36702f71 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -38,6 +38,8 @@ absl_cc_library( "internal/charconv_bigint.h" "internal/charconv_parse.cc" "internal/charconv_parse.h" + "internal/escaping.cc" + "internal/escaping.h" "internal/memutil.cc" "internal/memutil.h" "internal/stl_type_traits.h" diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc index d2fcd9c1..7adc1b65 100644 --- a/absl/strings/escaping.cc +++ b/absl/strings/escaping.cc @@ -26,6 +26,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/base/internal/unaligned_access.h" #include "absl/strings/internal/char_map.h" +#include "absl/strings/internal/escaping.h" #include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/internal/utf8.h" #include "absl/strings/str_cat.h" @@ -764,176 +765,9 @@ constexpr signed char kUnWebSafeBase64[] = { }; /* clang-format on */ -size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { - // Base64 encodes three bytes of input at a time. If the input is not - // divisible by three, we pad as appropriate. - // - // (from https://tools.ietf.org/html/rfc3548) - // Special processing is performed if fewer than 24 bits are available - // at the end of the data being encoded. A full encoding quantum is - // always completed at the end of a quantity. When fewer than 24 input - // bits are available in an input group, zero bits are added (on the - // right) to form an integral number of 6-bit groups. Padding at the - // end of the data is performed using the '=' character. Since all base - // 64 input is an integral number of octets, only the following cases - // can arise: - - // Base64 encodes each three bytes of input into four bytes of output. - size_t len = (input_len / 3) * 4; - - if (input_len % 3 == 0) { - // (from https://tools.ietf.org/html/rfc3548) - // (1) the final quantum of encoding input is an integral multiple of 24 - // bits; here, the final unit of encoded output will be an integral - // multiple of 4 characters with no "=" padding, - } else if (input_len % 3 == 1) { - // (from https://tools.ietf.org/html/rfc3548) - // (2) the final quantum of encoding input is exactly 8 bits; here, the - // final unit of encoded output will be two characters followed by two - // "=" padding characters, or - len += 2; - if (do_padding) { - len += 2; - } - } else { // (input_len % 3 == 2) - // (from https://tools.ietf.org/html/rfc3548) - // (3) the final quantum of encoding input is exactly 16 bits; here, the - // final unit of encoded output will be three characters followed by one - // "=" padding character. - len += 3; - if (do_padding) { - len += 1; - } - } - - assert(len >= input_len); // make sure we didn't overflow - return len; -} - -size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, - size_t szdest, const char* base64, - bool do_padding) { - static const char kPad64 = '='; - - if (szsrc * 4 > szdest * 3) return 0; - - char* cur_dest = dest; - const unsigned char* cur_src = src; - - char* const limit_dest = dest + szdest; - const unsigned char* const limit_src = src + szsrc; - - // Three bytes of data encodes to four characters of cyphertext. - // So we can pump through three-byte chunks atomically. - if (szsrc >= 3) { // "limit_src - 3" is UB if szsrc < 3. - while (cur_src < limit_src - 3) { // While we have >= 32 bits. - uint32_t in = absl::big_endian::Load32(cur_src) >> 8; - - cur_dest[0] = base64[in >> 18]; - in &= 0x3FFFF; - cur_dest[1] = base64[in >> 12]; - in &= 0xFFF; - cur_dest[2] = base64[in >> 6]; - in &= 0x3F; - cur_dest[3] = base64[in]; - - cur_dest += 4; - cur_src += 3; - } - } - // To save time, we didn't update szdest or szsrc in the loop. So do it now. - szdest = limit_dest - cur_dest; - szsrc = limit_src - cur_src; - - /* now deal with the tail (<=3 bytes) */ - switch (szsrc) { - case 0: - // Nothing left; nothing more to do. - break; - case 1: { - // One byte left: this encodes to two characters, and (optionally) - // two pad characters to round out the four-character cypherblock. - if (szdest < 2) return 0; - uint32_t in = cur_src[0]; - cur_dest[0] = base64[in >> 2]; - in &= 0x3; - cur_dest[1] = base64[in << 4]; - cur_dest += 2; - szdest -= 2; - if (do_padding) { - if (szdest < 2) return 0; - cur_dest[0] = kPad64; - cur_dest[1] = kPad64; - cur_dest += 2; - szdest -= 2; - } - break; - } - case 2: { - // Two bytes left: this encodes to three characters, and (optionally) - // one pad character to round out the four-character cypherblock. - if (szdest < 3) return 0; - uint32_t in = absl::big_endian::Load16(cur_src); - cur_dest[0] = base64[in >> 10]; - in &= 0x3FF; - cur_dest[1] = base64[in >> 4]; - in &= 0x00F; - cur_dest[2] = base64[in << 2]; - cur_dest += 3; - szdest -= 3; - if (do_padding) { - if (szdest < 1) return 0; - cur_dest[0] = kPad64; - cur_dest += 1; - szdest -= 1; - } - break; - } - case 3: { - // Three bytes left: same as in the big loop above. We can't do this in - // the loop because the loop above always reads 4 bytes, and the fourth - // byte is past the end of the input. - if (szdest < 4) return 0; - uint32_t in = (cur_src[0] << 16) + absl::big_endian::Load16(cur_src + 1); - cur_dest[0] = base64[in >> 18]; - in &= 0x3FFFF; - cur_dest[1] = base64[in >> 12]; - in &= 0xFFF; - cur_dest[2] = base64[in >> 6]; - in &= 0x3F; - cur_dest[3] = base64[in]; - cur_dest += 4; - szdest -= 4; - break; - } - default: - // Should not be reached: blocks of 4 bytes are handled - // in the while loop before this switch statement. - ABSL_RAW_LOG(FATAL, "Logic problem? szsrc = %zu", szsrc); - break; - } - return (cur_dest - dest); -} - -constexpr char kBase64Chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - constexpr char kWebSafeBase64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; -template -void Base64EscapeInternal(const unsigned char* src, size_t szsrc, String* dest, - bool do_padding, const char* base64_chars) { - const size_t calc_escaped_size = - CalculateBase64EscapedLenInternal(szsrc, do_padding); - strings_internal::STLStringResizeUninitialized(dest, calc_escaped_size); - - const size_t escaped_len = Base64EscapeInternal( - src, szsrc, &(*dest)[0], dest->size(), base64_chars, do_padding); - assert(calc_escaped_size == escaped_len); - dest->erase(escaped_len); -} - template bool Base64UnescapeInternal(const char* src, size_t slen, String* dest, const signed char* unbase64) { @@ -1068,26 +902,30 @@ bool WebSafeBase64Unescape(absl::string_view src, std::string* dest) { } void Base64Escape(absl::string_view src, std::string* dest) { - Base64EscapeInternal(reinterpret_cast(src.data()), - src.size(), dest, true, kBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast(src.data()), src.size(), dest, + true, strings_internal::kBase64Chars); } void WebSafeBase64Escape(absl::string_view src, std::string* dest) { - Base64EscapeInternal(reinterpret_cast(src.data()), - src.size(), dest, false, kWebSafeBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast(src.data()), src.size(), dest, + false, kWebSafeBase64Chars); } std::string Base64Escape(absl::string_view src) { std::string dest; - Base64EscapeInternal(reinterpret_cast(src.data()), - src.size(), &dest, true, kBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast(src.data()), src.size(), &dest, + true, strings_internal::kBase64Chars); return dest; } std::string WebSafeBase64Escape(absl::string_view src) { std::string dest; - Base64EscapeInternal(reinterpret_cast(src.data()), - src.size(), &dest, false, kWebSafeBase64Chars); + strings_internal::Base64EscapeInternal( + reinterpret_cast(src.data()), src.size(), &dest, + false, kWebSafeBase64Chars); return dest; } diff --git a/absl/strings/internal/escaping.cc b/absl/strings/internal/escaping.cc new file mode 100644 index 00000000..c5271286 --- /dev/null +++ b/absl/strings/internal/escaping.cc @@ -0,0 +1,180 @@ +// Copyright 2020 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. + +#include "absl/strings/internal/escaping.h" + +#include "absl/base/internal/endian.h" +#include "absl/base/internal/raw_logging.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace strings_internal { + +const char kBase64Chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { + // Base64 encodes three bytes of input at a time. If the input is not + // divisible by three, we pad as appropriate. + // + // (from https://tools.ietf.org/html/rfc3548) + // Special processing is performed if fewer than 24 bits are available + // at the end of the data being encoded. A full encoding quantum is + // always completed at the end of a quantity. When fewer than 24 input + // bits are available in an input group, zero bits are added (on the + // right) to form an integral number of 6-bit groups. Padding at the + // end of the data is performed using the '=' character. Since all base + // 64 input is an integral number of octets, only the following cases + // can arise: + + // Base64 encodes each three bytes of input into four bytes of output. + size_t len = (input_len / 3) * 4; + + if (input_len % 3 == 0) { + // (from https://tools.ietf.org/html/rfc3548) + // (1) the final quantum of encoding input is an integral multiple of 24 + // bits; here, the final unit of encoded output will be an integral + // multiple of 4 characters with no "=" padding, + } else if (input_len % 3 == 1) { + // (from https://tools.ietf.org/html/rfc3548) + // (2) the final quantum of encoding input is exactly 8 bits; here, the + // final unit of encoded output will be two characters followed by two + // "=" padding characters, or + len += 2; + if (do_padding) { + len += 2; + } + } else { // (input_len % 3 == 2) + // (from https://tools.ietf.org/html/rfc3548) + // (3) the final quantum of encoding input is exactly 16 bits; here, the + // final unit of encoded output will be three characters followed by one + // "=" padding character. + len += 3; + if (do_padding) { + len += 1; + } + } + + assert(len >= input_len); // make sure we didn't overflow + return len; +} + +size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, + size_t szdest, const char* base64, + bool do_padding) { + static const char kPad64 = '='; + + if (szsrc * 4 > szdest * 3) return 0; + + char* cur_dest = dest; + const unsigned char* cur_src = src; + + char* const limit_dest = dest + szdest; + const unsigned char* const limit_src = src + szsrc; + + // Three bytes of data encodes to four characters of cyphertext. + // So we can pump through three-byte chunks atomically. + if (szsrc >= 3) { // "limit_src - 3" is UB if szsrc < 3. + while (cur_src < limit_src - 3) { // While we have >= 32 bits. + uint32_t in = absl::big_endian::Load32(cur_src) >> 8; + + cur_dest[0] = base64[in >> 18]; + in &= 0x3FFFF; + cur_dest[1] = base64[in >> 12]; + in &= 0xFFF; + cur_dest[2] = base64[in >> 6]; + in &= 0x3F; + cur_dest[3] = base64[in]; + + cur_dest += 4; + cur_src += 3; + } + } + // To save time, we didn't update szdest or szsrc in the loop. So do it now. + szdest = limit_dest - cur_dest; + szsrc = limit_src - cur_src; + + /* now deal with the tail (<=3 bytes) */ + switch (szsrc) { + case 0: + // Nothing left; nothing more to do. + break; + case 1: { + // One byte left: this encodes to two characters, and (optionally) + // two pad characters to round out the four-character cypherblock. + if (szdest < 2) return 0; + uint32_t in = cur_src[0]; + cur_dest[0] = base64[in >> 2]; + in &= 0x3; + cur_dest[1] = base64[in << 4]; + cur_dest += 2; + szdest -= 2; + if (do_padding) { + if (szdest < 2) return 0; + cur_dest[0] = kPad64; + cur_dest[1] = kPad64; + cur_dest += 2; + szdest -= 2; + } + break; + } + case 2: { + // Two bytes left: this encodes to three characters, and (optionally) + // one pad character to round out the four-character cypherblock. + if (szdest < 3) return 0; + uint32_t in = absl::big_endian::Load16(cur_src); + cur_dest[0] = base64[in >> 10]; + in &= 0x3FF; + cur_dest[1] = base64[in >> 4]; + in &= 0x00F; + cur_dest[2] = base64[in << 2]; + cur_dest += 3; + szdest -= 3; + if (do_padding) { + if (szdest < 1) return 0; + cur_dest[0] = kPad64; + cur_dest += 1; + szdest -= 1; + } + break; + } + case 3: { + // Three bytes left: same as in the big loop above. We can't do this in + // the loop because the loop above always reads 4 bytes, and the fourth + // byte is past the end of the input. + if (szdest < 4) return 0; + uint32_t in = (cur_src[0] << 16) + absl::big_endian::Load16(cur_src + 1); + cur_dest[0] = base64[in >> 18]; + in &= 0x3FFFF; + cur_dest[1] = base64[in >> 12]; + in &= 0xFFF; + cur_dest[2] = base64[in >> 6]; + in &= 0x3F; + cur_dest[3] = base64[in]; + cur_dest += 4; + szdest -= 4; + break; + } + default: + // Should not be reached: blocks of 4 bytes are handled + // in the while loop before this switch statement. + ABSL_RAW_LOG(FATAL, "Logic problem? szsrc = %zu", szsrc); + break; + } + return (cur_dest - dest); +} + +} // namespace strings_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/absl/strings/internal/escaping.h b/absl/strings/internal/escaping.h new file mode 100644 index 00000000..6a9ce602 --- /dev/null +++ b/absl/strings/internal/escaping.h @@ -0,0 +1,58 @@ +// Copyright 2020 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. + +#ifndef ABSL_STRINGS_INTERNAL_ESCAPING_H_ +#define ABSL_STRINGS_INTERNAL_ESCAPING_H_ + +#include + +#include "absl/strings/internal/resize_uninitialized.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace strings_internal { + +ABSL_CONST_INIT extern const char kBase64Chars[]; + +// Calculates how long a string will be when it is base64 encoded given its +// length and whether or not the result should be padded. +size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding); + +// Base64-encodes `src` using the alphabet provided in `base64` and writes the +// result to `dest`. If `do_padding` is true, `dest` is padded with '=' chars +// until its length is a multiple of 3. Returns the length of `dest`. +size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, + size_t szdest, const char* base64, bool do_padding); + +// Base64-encodes `src` using the alphabet provided in `base64` and writes the +// result to `dest`. If `do_padding` is true, `dest` is padded with '=' chars +// until its length is a multiple of 3. +template +void Base64EscapeInternal(const unsigned char* src, size_t szsrc, String* dest, + bool do_padding, const char* base64_chars) { + const size_t calc_escaped_size = + CalculateBase64EscapedLenInternal(szsrc, do_padding); + STLStringResizeUninitialized(dest, calc_escaped_size); + + const size_t escaped_len = Base64EscapeInternal( + src, szsrc, &(*dest)[0], dest->size(), base64_chars, do_padding); + assert(calc_escaped_size == escaped_len); + dest->erase(escaped_len); +} + +} // namespace strings_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STRINGS_INTERNAL_ESCAPING_H_ diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 4b34e563..4f7dd6b3 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -122,7 +122,7 @@ ABSL_NAMESPACE_BEGIN // // You may create a null `string_view` in two ways: // -// absl::string_view sv(); +// absl::string_view sv; // absl::string_view sv(nullptr, 0); // // For the above, `sv.data() == nullptr`, `sv.length() == 0`, and @@ -605,7 +605,7 @@ inline string_view ClippedSubstr(string_view s, size_t pos, // Creates an `absl::string_view` from a pointer `p` even if it's null-valued. // This function should be used where an `absl::string_view` can be created from // a possibly-null pointer. -inline string_view NullSafeStringView(const char* p) { +constexpr string_view NullSafeStringView(const char* p) { return p ? string_view(p) : string_view(); } diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc index 96dacdf0..c4fbd16c 100644 --- a/absl/strings/string_view_test.cc +++ b/absl/strings/string_view_test.cc @@ -931,6 +931,31 @@ TEST(StringViewTest, NullSafeStringView) { } } +TEST(StringViewTest, ConstexprNullSafeStringView) { + { + constexpr absl::string_view s = absl::NullSafeStringView(nullptr); + EXPECT_EQ(nullptr, s.data()); + EXPECT_EQ(0, s.size()); + EXPECT_EQ(absl::string_view(), s); + } +#if !defined(_MSC_VER) || _MSC_VER >= 1910 + // MSVC 2017+ is required for good constexpr string_view support. + // See the implementation of `absl::string_view::StrlenInternal()`. + { + static constexpr char kHi[] = "hi"; + absl::string_view s = absl::NullSafeStringView(kHi); + EXPECT_EQ(kHi, s.data()); + EXPECT_EQ(strlen(kHi), s.size()); + EXPECT_EQ(absl::string_view("hi"), s); + } + { + constexpr absl::string_view s = absl::NullSafeStringView("hello"); + EXPECT_EQ(s.size(), 5); + EXPECT_EQ("hello", s); + } +#endif +} + TEST(StringViewTest, ConstexprCompiles) { constexpr absl::string_view sp; #ifdef ABSL_HAVE_STRING_VIEW_FROM_NULLPTR diff --git a/ci/absl_types_options.h b/ci/absl_types_options.h index 8f8ed34a..307fde64 100644 --- a/ci/absl_types_options.h +++ b/ci/absl_types_options.h @@ -22,6 +22,7 @@ #define ABSL_OPTION_USE_STD_OPTIONAL 0 #define ABSL_OPTION_USE_STD_STRING_VIEW 0 #define ABSL_OPTION_USE_STD_VARIANT 0 - +#define ABSL_OPTION_USE_INLINE_NAMESPACE 1 +#define ABSL_OPTION_INLINE_NAMESPACE_NAME ns #endif // ABSL_BASE_OPTIONS_H_ diff --git a/ci/linux_gcc-latest_libstdcxx_bazel.sh b/ci/linux_gcc-latest_libstdcxx_bazel.sh index 2d41d511..59647031 100755 --- a/ci/linux_gcc-latest_libstdcxx_bazel.sh +++ b/ci/linux_gcc-latest_libstdcxx_bazel.sh @@ -55,7 +55,8 @@ for std in ${STD}; do for exceptions_mode in ${EXCEPTIONS_MODE}; do echo "--------------------------------------------------------------------" time docker run \ - --volume="${ABSEIL_ROOT}:/abseil-cpp:ro" \ + --volume="${ABSEIL_ROOT}:/abseil-cpp-ro:ro" \ + --tmpfs=/abseil-cpp \ --workdir=/abseil-cpp \ --cap-add=SYS_PTRACE \ --rm \ @@ -63,18 +64,23 @@ for std in ${STD}; do -e BAZEL_CXXOPTS="-std=${std}" \ ${DOCKER_EXTRA_ARGS:-} \ ${DOCKER_CONTAINER} \ - /usr/local/bin/bazel test ... \ - --compilation_mode="${compilation_mode}" \ - --copt="${exceptions_mode}" \ - --copt=-Werror \ - --define="absl=1" \ - --keep_going \ - --show_timestamps \ - --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" \ - --test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \ - --test_output=errors \ - --test_tag_filters=-benchmark \ - ${BAZEL_EXTRA_ARGS:-} + /bin/sh -c " + cp -r /abseil-cpp-ro/* /abseil-cpp/ + if [ -n \"${ALTERNATE_OPTIONS:-}\" ]; then + cp ${ALTERNATE_OPTIONS:-} absl/base/options.h || exit 1 + fi + /usr/local/bin/bazel test ... \ + --compilation_mode=\"${compilation_mode}\" \ + --copt=\"${exceptions_mode}\" \ + --copt=-Werror \ + --define=\"absl=1\" \ + --keep_going \ + --show_timestamps \ + --test_env=\"GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1\" \ + --test_env=\"TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo\" \ + --test_output=errors \ + --test_tag_filters=-benchmark \ + ${BAZEL_EXTRA_ARGS:-}" done done done diff --git a/ci/macos_xcode_bazel.sh b/ci/macos_xcode_bazel.sh index 3cf1be4a..f5f2d759 100755 --- a/ci/macos_xcode_bazel.sh +++ b/ci/macos_xcode_bazel.sh @@ -41,6 +41,10 @@ echo "---------------" cd ${ABSEIL_ROOT} +if [ -n "${ALTERNATE_OPTIONS:-}" ]; then + cp ${ALTERNATE_OPTIONS:-} absl/base/options.h || exit 1 +fi + ${BAZEL_BIN} test ... \ --copt=-Werror \ --keep_going \ -- cgit v1.2.3 From 159bf2bf6d1cc8087e02468d071e94d1177d1bae Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 16 Jan 2020 13:38:39 -0800 Subject: Export of internal Abseil changes -- c42a234e2c186bf697ce8d77e85628601fa514a6 by Abseil Team : Enable the assertion in the iterator's operator++ PiperOrigin-RevId: 290134813 -- f8c53ba8e9c5bb16bbcc1e412a5c2519c912c83e by Abseil Team : Define operator== and operator!= for absl::{weak,strong}_equality and absl::{partial,weak,strong}_ordering types themselves. PiperOrigin-RevId: 290111564 -- 36bc574090cefad74a451719ce2761982647a51d by Tom Manshreck : Specify Time library flag formats PiperOrigin-RevId: 289928010 -- 26dd40281add260baab2b60fec05dfb9c5304aaa by Mark Barolak : Delete an extraneous forward declaration of absl::Cord. PiperOrigin-RevId: 289708481 -- e60aea7f33554ff66d7699bb70e7af1d26323f1d by Abseil Team : Release b-tree benchmarks. PiperOrigin-RevId: 289654429 -- 660aa83fa000d4bae072b2d1c790f81d0939bc7e by Greg Falcon : Use https links. Import of https://github.com/abseil/abseil-cpp/pull/586 PiperOrigin-RevId: 289479559 -- 0611ea4482dcf23d6b0a0389fe041eeb9052449a by Derek Mauro : Removes the static initializer for LookupTables::kVmaxOverBase Uses template specialization to hard code the resulting array. Static initializers are problematic for a number of reasons. Not only are they responsible for the static initialization order fiasco, but they are in the critical path during program startup. For these reasons, the Google C++ style guide strongly discourages them (and forbids them when they are not trivially destructible), and Chromium even has a test forbidding them. https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables https://chromium.googlesource.com/chromium/src.git/+/master/docs/static_initializers.md http://neugierig.org/software/chromium/notes/2011/08/static-initializers.html PiperOrigin-RevId: 289458677 -- c869362f6bb7a872314f74750d38d81bdaa73f95 by Greg Falcon : Step 2 of 2 to fix our CCTZ fork to respect inline namespaces. Re-import of CCTZ from GitHub, applying new changes to honor Abseil's optional inline namespace in MSVC. PiperOrigin-RevId: 289454407 -- fdb3474d76c2ee0371ccdf7593a78137c03a3f58 by Greg Falcon : Step 1 of 2 to fix our CCTZ fork to respect inline namespaces. CCTZ uses a linker flag to simulate weak symbol support in MSVC. This takes the form of a #pragma that includes the mangled names of two types: the symbol to treat as weak, and the symbol to use as its default value if no override is provided. When Abseil is configured to use inline namespaces, the mangled names of these symbols change, and the pragma should change to reflect that. Fortunately for us, MSVC name mangling is simple enough that we can generate the needed string literals in the preprocessor. This CL introduces the new macros; the uses will be introduced in a follow-up CL. PiperOrigin-RevId: 289435599 -- 5f152cc36f008acb9ab78f30b5efa40ebaf2754b by Matt Kulukundis : Improve documentation for lazy_emplace PiperOrigin-RevId: 289333112 GitOrigin-RevId: c42a234e2c186bf697ce8d77e85628601fa514a6 Change-Id: I139ce6c7044a70d083af53e428bcb987f0fd88c6 --- absl/base/config.h | 28 +- absl/container/BUILD.bazel | 26 + absl/container/btree_benchmark.cc | 707 ++++++++++++++++++++++++ absl/container/internal/raw_hash_set.h | 15 +- absl/flags/marshalling.h | 6 +- absl/strings/internal/str_format/extension.h | 3 - absl/strings/numbers.cc | 52 +- absl/time/internal/cctz/src/zone_info_source.cc | 40 +- absl/time/time.h | 76 ++- absl/types/compare.h | 40 ++ absl/types/compare_test.cc | 92 ++- 11 files changed, 1025 insertions(+), 60 deletions(-) create mode 100644 absl/container/btree_benchmark.cc (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index edbf2246..c4e8dce4 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -66,6 +66,10 @@ #include "absl/base/options.h" #include "absl/base/policy_checks.h" +// Helper macro to convert a CPP variable to a string literal. +#define ABSL_INTERNAL_DO_TOKEN_STR(x) #x +#define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x) + // ----------------------------------------------------------------------------- // Abseil namespace annotations // ----------------------------------------------------------------------------- @@ -98,8 +102,6 @@ // Check that ABSL_OPTION_INLINE_NAMESPACE_NAME is neither "head" nor "" #if defined(__cplusplus) && ABSL_OPTION_USE_INLINE_NAMESPACE == 1 -#define ABSL_INTERNAL_DO_TOKEN_STR(x) #x -#define ABSL_INTERNAL_TOKEN_STR(x) ABSL_INTERNAL_DO_TOKEN_STR(x) #define ABSL_INTERNAL_INLINE_NAMESPACE_STR \ ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME) @@ -617,6 +619,28 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_INTERNAL_MSVC_2017_DBG_MODE #endif +// ABSL_INTERNAL_MANGLED_NS +// ABSL_INTERNAL_MANGLED_BACKREFERENCE +// +// Internal macros for building up mangled names in our internal fork of CCTZ. +// This implementation detail is only needed and provided for the MSVC build. +// +// These macros both expand to string literals. ABSL_INTERNAL_MANGLED_NS is +// the mangled spelling of the `absl` namespace, and +// ABSL_INTERNAL_MANGLED_BACKREFERENCE is a back-reference integer representing +// the proper count to skip past the CCTZ fork namespace names. (This number +// is one larger when there is an inline namespace name to skip.) +#if defined(_MSC_VER) +#if ABSL_OPTION_USE_INLINE_NAMESPACE == 0 +#define ABSL_INTERNAL_MANGLED_NS "absl" +#define ABSL_INTERNAL_MANGLED_BACKREFERENCE "5" +#else +#define ABSL_INTERNAL_MANGLED_NS \ + ABSL_INTERNAL_TOKEN_STR(ABSL_OPTION_INLINE_NAMESPACE_NAME) "@absl" +#define ABSL_INTERNAL_MANGLED_BACKREFERENCE "6" +#endif +#endif + #undef ABSL_INTERNAL_HAS_KEYWORD #endif // ABSL_BASE_CONFIG_H_ diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 1f7abe07..f2217140 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -874,3 +874,29 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_binary( + name = "btree_benchmark", + testonly = 1, + srcs = [ + "btree_benchmark.cc", + ], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + tags = ["benchmark"], + visibility = ["//visibility:private"], + deps = [ + ":btree", + ":btree_test_common", + ":flat_hash_map", + ":flat_hash_set", + ":hashtable_debug", + "//absl/base:raw_logging_internal", + "//absl/flags:flag", + "//absl/hash", + "//absl/memory", + "//absl/strings:str_format", + "//absl/time", + "@com_github_google_benchmark//:benchmark_main", + ], +) diff --git a/absl/container/btree_benchmark.cc b/absl/container/btree_benchmark.cc new file mode 100644 index 00000000..4af92f9f --- /dev/null +++ b/absl/container/btree_benchmark.cc @@ -0,0 +1,707 @@ +// Copyright 2018 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. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/base/internal/raw_logging.h" +#include "absl/container/btree_map.h" +#include "absl/container/btree_set.h" +#include "absl/container/btree_test.h" +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" +#include "absl/container/internal/hashtable_debug.h" +#include "absl/flags/flag.h" +#include "absl/hash/hash.h" +#include "absl/memory/memory.h" +#include "absl/strings/str_format.h" +#include "absl/time/time.h" +#include "benchmark/benchmark.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace container_internal { +namespace { + +constexpr size_t kBenchmarkValues = 1 << 20; + +// How many times we add and remove sub-batches in one batch of *AddRem +// benchmarks. +constexpr size_t kAddRemBatchSize = 1 << 2; + +// Generates n values in the range [0, 4 * n]. +template +std::vector GenerateValues(int n) { + constexpr int kSeed = 23; + return GenerateValuesWithSeed(n, 4 * n, kSeed); +} + +// Benchmark insertion of values into a container. +template +void BM_InsertImpl(benchmark::State& state, bool sorted) { + using V = typename remove_pair_const::type; + typename KeyOfValue::type key_of_value; + + std::vector values = GenerateValues(kBenchmarkValues); + if (sorted) { + std::sort(values.begin(), values.end()); + } + T container(values.begin(), values.end()); + + // Remove and re-insert 10% of the keys per batch. + const int batch_size = (kBenchmarkValues + 9) / 10; + while (state.KeepRunningBatch(batch_size)) { + state.PauseTiming(); + const auto i = static_cast(state.iterations()); + + for (int j = i; j < i + batch_size; j++) { + int x = j % kBenchmarkValues; + container.erase(key_of_value(values[x])); + } + + state.ResumeTiming(); + + for (int j = i; j < i + batch_size; j++) { + int x = j % kBenchmarkValues; + container.insert(values[x]); + } + } +} + +template +void BM_Insert(benchmark::State& state) { + BM_InsertImpl(state, false); +} + +template +void BM_InsertSorted(benchmark::State& state) { + BM_InsertImpl(state, true); +} + +// container::insert sometimes returns a pair and sometimes +// returns an iterator (for multi- containers). +template +Iter GetIterFromInsert(const std::pair& pair) { + return pair.first; +} +template +Iter GetIterFromInsert(const Iter iter) { + return iter; +} + +// Benchmark insertion of values into a container at the end. +template +void BM_InsertEnd(benchmark::State& state) { + using V = typename remove_pair_const::type; + typename KeyOfValue::type key_of_value; + + T container; + const int kSize = 10000; + for (int i = 0; i < kSize; ++i) { + container.insert(Generator(kSize)(i)); + } + V v = Generator(kSize)(kSize - 1); + typename T::key_type k = key_of_value(v); + + auto it = container.find(k); + while (state.KeepRunning()) { + // Repeatedly removing then adding v. + container.erase(it); + it = GetIterFromInsert(container.insert(v)); + } +} + +template +void BM_LookupImpl(benchmark::State& state, bool sorted) { + using V = typename remove_pair_const::type; + typename KeyOfValue::type key_of_value; + + std::vector values = GenerateValues(kBenchmarkValues); + if (sorted) { + std::sort(values.begin(), values.end()); + } + T container(values.begin(), values.end()); + + while (state.KeepRunning()) { + int idx = state.iterations() % kBenchmarkValues; + benchmark::DoNotOptimize(container.find(key_of_value(values[idx]))); + } +} + +// Benchmark lookup of values in a container. +template +void BM_Lookup(benchmark::State& state) { + BM_LookupImpl(state, false); +} + +// Benchmark lookup of values in a full container, meaning that values +// are inserted in-order to take advantage of biased insertion, which +// yields a full tree. +template +void BM_FullLookup(benchmark::State& state) { + BM_LookupImpl(state, true); +} + +// Benchmark deletion of values from a container. +template +void BM_Delete(benchmark::State& state) { + using V = typename remove_pair_const::type; + typename KeyOfValue::type key_of_value; + std::vector values = GenerateValues(kBenchmarkValues); + T container(values.begin(), values.end()); + + // Remove and re-insert 10% of the keys per batch. + const int batch_size = (kBenchmarkValues + 9) / 10; + while (state.KeepRunningBatch(batch_size)) { + const int i = state.iterations(); + + for (int j = i; j < i + batch_size; j++) { + int x = j % kBenchmarkValues; + container.erase(key_of_value(values[x])); + } + + state.PauseTiming(); + for (int j = i; j < i + batch_size; j++) { + int x = j % kBenchmarkValues; + container.insert(values[x]); + } + state.ResumeTiming(); + } +} + +// Benchmark deletion of multiple values from a container. +template +void BM_DeleteRange(benchmark::State& state) { + using V = typename remove_pair_const::type; + typename KeyOfValue::type key_of_value; + std::vector values = GenerateValues(kBenchmarkValues); + T container(values.begin(), values.end()); + + // Remove and re-insert 10% of the keys per batch. + const int batch_size = (kBenchmarkValues + 9) / 10; + while (state.KeepRunningBatch(batch_size)) { + const int i = state.iterations(); + + const int start_index = i % kBenchmarkValues; + + state.PauseTiming(); + { + std::vector removed; + removed.reserve(batch_size); + auto itr = container.find(key_of_value(values[start_index])); + auto start = itr; + for (int j = 0; j < batch_size; j++) { + if (itr == container.end()) { + state.ResumeTiming(); + container.erase(start, itr); + state.PauseTiming(); + itr = container.begin(); + start = itr; + } + removed.push_back(*itr++); + } + + state.ResumeTiming(); + container.erase(start, itr); + state.PauseTiming(); + + container.insert(removed.begin(), removed.end()); + } + state.ResumeTiming(); + } +} + +// Benchmark steady-state insert (into first half of range) and remove (from +// second half of range), treating the container approximately like a queue with +// log-time access for all elements. This benchmark does not test the case where +// insertion and removal happen in the same region of the tree. This benchmark +// counts two value constructors. +template +void BM_QueueAddRem(benchmark::State& state) { + using V = typename remove_pair_const::type; + typename KeyOfValue::type key_of_value; + + ABSL_RAW_CHECK(kBenchmarkValues % 2 == 0, "for performance"); + + T container; + + const size_t half = kBenchmarkValues / 2; + std::vector remove_keys(half); + std::vector add_keys(half); + + // We want to do the exact same work repeatedly, and the benchmark can end + // after a different number of iterations depending on the speed of the + // individual run so we use a large batch size here and ensure that we do + // deterministic work every batch. + while (state.KeepRunningBatch(half * kAddRemBatchSize)) { + state.PauseTiming(); + + container.clear(); + + for (size_t i = 0; i < half; ++i) { + remove_keys[i] = i; + add_keys[i] = i; + } + constexpr int kSeed = 5; + std::mt19937_64 rand(kSeed); + std::shuffle(remove_keys.begin(), remove_keys.end(), rand); + std::shuffle(add_keys.begin(), add_keys.end(), rand); + + // Note needs lazy generation of values. + Generator g(kBenchmarkValues * kAddRemBatchSize); + + for (size_t i = 0; i < half; ++i) { + container.insert(g(add_keys[i])); + container.insert(g(half + remove_keys[i])); + } + + // There are three parts each of size "half": + // 1 is being deleted from [offset - half, offset) + // 2 is standing [offset, offset + half) + // 3 is being inserted into [offset + half, offset + 2 * half) + size_t offset = 0; + + for (size_t i = 0; i < kAddRemBatchSize; ++i) { + std::shuffle(remove_keys.begin(), remove_keys.end(), rand); + std::shuffle(add_keys.begin(), add_keys.end(), rand); + offset += half; + + state.ResumeTiming(); + for (size_t idx = 0; idx < half; ++idx) { + container.erase(key_of_value(g(offset - half + remove_keys[idx]))); + container.insert(g(offset + half + add_keys[idx])); + } + state.PauseTiming(); + } + state.ResumeTiming(); + } +} + +// Mixed insertion and deletion in the same range using pre-constructed values. +template +void BM_MixedAddRem(benchmark::State& state) { + using V = typename remove_pair_const::type; + typename KeyOfValue::type key_of_value; + + ABSL_RAW_CHECK(kBenchmarkValues % 2 == 0, "for performance"); + + T container; + + // Create two random shuffles + std::vector remove_keys(kBenchmarkValues); + std::vector add_keys(kBenchmarkValues); + + // We want to do the exact same work repeatedly, and the benchmark can end + // after a different number of iterations depending on the speed of the + // individual run so we use a large batch size here and ensure that we do + // deterministic work every batch. + while (state.KeepRunningBatch(kBenchmarkValues * kAddRemBatchSize)) { + state.PauseTiming(); + + container.clear(); + + constexpr int kSeed = 7; + std::mt19937_64 rand(kSeed); + + std::vector values = GenerateValues(kBenchmarkValues * 2); + + // Insert the first half of the values (already in random order) + container.insert(values.begin(), values.begin() + kBenchmarkValues); + + // Insert the first half of the values (already in random order) + for (size_t i = 0; i < kBenchmarkValues; ++i) { + // remove_keys and add_keys will be swapped before each round, + // therefore fill add_keys here w/ the keys being inserted, so + // they'll be the first to be removed. + remove_keys[i] = i + kBenchmarkValues; + add_keys[i] = i; + } + + for (size_t i = 0; i < kAddRemBatchSize; ++i) { + remove_keys.swap(add_keys); + std::shuffle(remove_keys.begin(), remove_keys.end(), rand); + std::shuffle(add_keys.begin(), add_keys.end(), rand); + + state.ResumeTiming(); + for (size_t idx = 0; idx < kBenchmarkValues; ++idx) { + container.erase(key_of_value(values[remove_keys[idx]])); + container.insert(values[add_keys[idx]]); + } + state.PauseTiming(); + } + state.ResumeTiming(); + } +} + +// Insertion at end, removal from the beginning. This benchmark +// counts two value constructors. +// TODO(ezb): we could add a GenerateNext version of generator that could reduce +// noise for string-like types. +template +void BM_Fifo(benchmark::State& state) { + using V = typename remove_pair_const::type; + + T container; + // Need lazy generation of values as state.max_iterations is large. + Generator g(kBenchmarkValues + state.max_iterations); + + for (int i = 0; i < kBenchmarkValues; i++) { + container.insert(g(i)); + } + + while (state.KeepRunning()) { + container.erase(container.begin()); + container.insert(container.end(), g(state.iterations() + kBenchmarkValues)); + } +} + +// Iteration (forward) through the tree +template +void BM_FwdIter(benchmark::State& state) { + using V = typename remove_pair_const::type; + using R = typename T::value_type const*; + + std::vector values = GenerateValues(kBenchmarkValues); + T container(values.begin(), values.end()); + + auto iter = container.end(); + + R r = nullptr; + + while (state.KeepRunning()) { + if (iter == container.end()) iter = container.begin(); + r = &(*iter); + ++iter; + } + + benchmark::DoNotOptimize(r); +} + +// Benchmark random range-construction of a container. +template +void BM_RangeConstructionImpl(benchmark::State& state, bool sorted) { + using V = typename remove_pair_const::type; + + std::vector values = GenerateValues(kBenchmarkValues); + if (sorted) { + std::sort(values.begin(), values.end()); + } + { + T container(values.begin(), values.end()); + } + + while (state.KeepRunning()) { + T container(values.begin(), values.end()); + benchmark::DoNotOptimize(container); + } +} + +template +void BM_InsertRangeRandom(benchmark::State& state) { + BM_RangeConstructionImpl(state, false); +} + +template +void BM_InsertRangeSorted(benchmark::State& state) { + BM_RangeConstructionImpl(state, true); +} + +#define STL_ORDERED_TYPES(value) \ + using stl_set_##value = std::set; \ + using stl_map_##value = std::map; \ + using stl_multiset_##value = std::multiset; \ + using stl_multimap_##value = std::multimap + +using StdString = std::string; +STL_ORDERED_TYPES(int32_t); +STL_ORDERED_TYPES(int64_t); +STL_ORDERED_TYPES(StdString); +STL_ORDERED_TYPES(Time); + +#define STL_UNORDERED_TYPES(value) \ + using stl_unordered_set_##value = std::unordered_set; \ + using stl_unordered_map_##value = std::unordered_map; \ + using flat_hash_set_##value = flat_hash_set; \ + using flat_hash_map_##value = flat_hash_map; \ + using stl_unordered_multiset_##value = std::unordered_multiset; \ + using stl_unordered_multimap_##value = \ + std::unordered_multimap + +#define STL_UNORDERED_TYPES_CUSTOM_HASH(value, hash) \ + using stl_unordered_set_##value = std::unordered_set; \ + using stl_unordered_map_##value = std::unordered_map; \ + using flat_hash_set_##value = flat_hash_set; \ + using flat_hash_map_##value = flat_hash_map; \ + using stl_unordered_multiset_##value = std::unordered_multiset; \ + using stl_unordered_multimap_##value = \ + std::unordered_multimap + +STL_UNORDERED_TYPES(int32_t); +STL_UNORDERED_TYPES(int64_t); +STL_UNORDERED_TYPES(StdString); +STL_UNORDERED_TYPES_CUSTOM_HASH(Time, absl::Hash); + +#define BTREE_TYPES(value) \ + using btree_256_set_##value = \ + btree_set, std::allocator>; \ + using btree_256_map_##value = \ + btree_map, \ + std::allocator>>; \ + using btree_256_multiset_##value = \ + btree_multiset, std::allocator>; \ + using btree_256_multimap_##value = \ + btree_multimap, \ + std::allocator>> + +BTREE_TYPES(int32_t); +BTREE_TYPES(int64_t); +BTREE_TYPES(StdString); +BTREE_TYPES(Time); + +#define MY_BENCHMARK4(type, func) \ + void BM_##type##_##func(benchmark::State& state) { BM_##func(state); } \ + BENCHMARK(BM_##type##_##func) + +#define MY_BENCHMARK3(type) \ + MY_BENCHMARK4(type, Insert); \ + MY_BENCHMARK4(type, InsertSorted); \ + MY_BENCHMARK4(type, InsertEnd); \ + MY_BENCHMARK4(type, Lookup); \ + MY_BENCHMARK4(type, FullLookup); \ + MY_BENCHMARK4(type, Delete); \ + MY_BENCHMARK4(type, DeleteRange); \ + MY_BENCHMARK4(type, QueueAddRem); \ + MY_BENCHMARK4(type, MixedAddRem); \ + MY_BENCHMARK4(type, Fifo); \ + MY_BENCHMARK4(type, FwdIter); \ + MY_BENCHMARK4(type, InsertRangeRandom); \ + MY_BENCHMARK4(type, InsertRangeSorted) + +#define MY_BENCHMARK2_SUPPORTS_MULTI_ONLY(type) \ + MY_BENCHMARK3(stl_##type); \ + MY_BENCHMARK3(stl_unordered_##type); \ + MY_BENCHMARK3(btree_256_##type) + +#define MY_BENCHMARK2(type) \ + MY_BENCHMARK2_SUPPORTS_MULTI_ONLY(type); \ + MY_BENCHMARK3(flat_hash_##type) + +// Define MULTI_TESTING to see benchmarks for multi-containers also. +// +// You can use --copt=-DMULTI_TESTING. +#ifdef MULTI_TESTING +#define MY_BENCHMARK(type) \ + MY_BENCHMARK2(set_##type); \ + MY_BENCHMARK2(map_##type); \ + MY_BENCHMARK2_SUPPORTS_MULTI_ONLY(multiset_##type); \ + MY_BENCHMARK2_SUPPORTS_MULTI_ONLY(multimap_##type) +#else +#define MY_BENCHMARK(type) \ + MY_BENCHMARK2(set_##type); \ + MY_BENCHMARK2(map_##type) +#endif + +MY_BENCHMARK(int32_t); +MY_BENCHMARK(int64_t); +MY_BENCHMARK(StdString); +MY_BENCHMARK(Time); + +// Define a type whose size and cost of moving are independently customizable. +// When sizeof(value_type) increases, we expect btree to no longer have as much +// cache-locality advantage over STL. When cost of moving increases, we expect +// btree to actually do more work than STL because it has to move values around +// and STL doesn't have to. +template +struct BigType { + BigType() : BigType(0) {} + explicit BigType(int x) { std::iota(values.begin(), values.end(), x); } + + void Copy(const BigType& x) { + for (int i = 0; i < Size && i < Copies; ++i) values[i] = x.values[i]; + // If Copies > Size, do extra copies. + for (int i = Size, idx = 0; i < Copies; ++i) { + int64_t tmp = x.values[idx]; + benchmark::DoNotOptimize(tmp); + idx = idx + 1 == Size ? 0 : idx + 1; + } + } + + BigType(const BigType& x) { Copy(x); } + BigType& operator=(const BigType& x) { + Copy(x); + return *this; + } + + // Compare only the first Copies elements if Copies is less than Size. + bool operator<(const BigType& other) const { + return std::lexicographical_compare( + values.begin(), values.begin() + std::min(Size, Copies), + other.values.begin(), other.values.begin() + std::min(Size, Copies)); + } + bool operator==(const BigType& other) const { + return std::equal(values.begin(), values.begin() + std::min(Size, Copies), + other.values.begin()); + } + + // Support absl::Hash. + template + friend State AbslHashValue(State h, const BigType& b) { + for (int i = 0; i < Size && i < Copies; ++i) + h = State::combine(std::move(h), b.values[i]); + return h; + } + + std::array values; +}; + +#define BIG_TYPE_BENCHMARKS(SIZE, COPIES) \ + using stl_set_size##SIZE##copies##COPIES = std::set>; \ + using stl_map_size##SIZE##copies##COPIES = \ + std::map, intptr_t>; \ + using stl_multiset_size##SIZE##copies##COPIES = \ + std::multiset>; \ + using stl_multimap_size##SIZE##copies##COPIES = \ + std::multimap, intptr_t>; \ + using stl_unordered_set_size##SIZE##copies##COPIES = \ + std::unordered_set, \ + absl::Hash>>; \ + using stl_unordered_map_size##SIZE##copies##COPIES = \ + std::unordered_map, intptr_t, \ + absl::Hash>>; \ + using flat_hash_set_size##SIZE##copies##COPIES = \ + flat_hash_set>; \ + using flat_hash_map_size##SIZE##copies##COPIES = \ + flat_hash_map, intptr_t>; \ + using stl_unordered_multiset_size##SIZE##copies##COPIES = \ + std::unordered_multiset, \ + absl::Hash>>; \ + using stl_unordered_multimap_size##SIZE##copies##COPIES = \ + std::unordered_multimap, intptr_t, \ + absl::Hash>>; \ + using btree_256_set_size##SIZE##copies##COPIES = \ + btree_set>; \ + using btree_256_map_size##SIZE##copies##COPIES = \ + btree_map, intptr_t>; \ + using btree_256_multiset_size##SIZE##copies##COPIES = \ + btree_multiset>; \ + using btree_256_multimap_size##SIZE##copies##COPIES = \ + btree_multimap, intptr_t>; \ + MY_BENCHMARK(size##SIZE##copies##COPIES) + +// Define BIG_TYPE_TESTING to see benchmarks for more big types. +// +// You can use --copt=-DBIG_TYPE_TESTING. +#ifndef NODESIZE_TESTING +#ifdef BIG_TYPE_TESTING +BIG_TYPE_BENCHMARKS(1, 4); +BIG_TYPE_BENCHMARKS(4, 1); +BIG_TYPE_BENCHMARKS(4, 4); +BIG_TYPE_BENCHMARKS(1, 8); +BIG_TYPE_BENCHMARKS(8, 1); +BIG_TYPE_BENCHMARKS(8, 8); +BIG_TYPE_BENCHMARKS(1, 16); +BIG_TYPE_BENCHMARKS(16, 1); +BIG_TYPE_BENCHMARKS(16, 16); +BIG_TYPE_BENCHMARKS(1, 32); +BIG_TYPE_BENCHMARKS(32, 1); +BIG_TYPE_BENCHMARKS(32, 32); +#else +BIG_TYPE_BENCHMARKS(32, 32); +#endif +#endif + +// Benchmark using unique_ptrs to large value types. In order to be able to use +// the same benchmark code as the other types, use a type that holds a +// unique_ptr and has a copy constructor. +template +struct BigTypePtr { + BigTypePtr() : BigTypePtr(0) {} + explicit BigTypePtr(int x) { + ptr = absl::make_unique>(x); + } + BigTypePtr(const BigTypePtr& x) { + ptr = absl::make_unique>(*x.ptr); + } + BigTypePtr(BigTypePtr&& x) noexcept = default; + BigTypePtr& operator=(const BigTypePtr& x) { + ptr = absl::make_unique>(*x.ptr); + } + BigTypePtr& operator=(BigTypePtr&& x) noexcept = default; + + bool operator<(const BigTypePtr& other) const { return *ptr < *other.ptr; } + bool operator==(const BigTypePtr& other) const { return *ptr == *other.ptr; } + + std::unique_ptr> ptr; +}; + +template +double ContainerInfo(const btree_set>& b) { + const double bytes_used = + b.bytes_used() + b.size() * sizeof(BigType); + const double bytes_per_value = bytes_used / b.size(); + BtreeContainerInfoLog(b, bytes_used, bytes_per_value); + return bytes_per_value; +} +template +double ContainerInfo(const btree_map>& b) { + const double bytes_used = + b.bytes_used() + b.size() * sizeof(BigType); + const double bytes_per_value = bytes_used / b.size(); + BtreeContainerInfoLog(b, bytes_used, bytes_per_value); + return bytes_per_value; +} + +#define BIG_TYPE_PTR_BENCHMARKS(SIZE) \ + using stl_set_size##SIZE##copies##SIZE##ptr = std::set>; \ + using stl_map_size##SIZE##copies##SIZE##ptr = \ + std::map>; \ + using stl_unordered_set_size##SIZE##copies##SIZE##ptr = \ + std::unordered_set, \ + absl::Hash>>; \ + using stl_unordered_map_size##SIZE##copies##SIZE##ptr = \ + std::unordered_map>; \ + using flat_hash_set_size##SIZE##copies##SIZE##ptr = \ + flat_hash_set>; \ + using flat_hash_map_size##SIZE##copies##SIZE##ptr = \ + flat_hash_map>; \ + using btree_256_set_size##SIZE##copies##SIZE##ptr = \ + btree_set>; \ + using btree_256_map_size##SIZE##copies##SIZE##ptr = \ + btree_map>; \ + MY_BENCHMARK3(stl_set_size##SIZE##copies##SIZE##ptr); \ + MY_BENCHMARK3(stl_unordered_set_size##SIZE##copies##SIZE##ptr); \ + MY_BENCHMARK3(flat_hash_set_size##SIZE##copies##SIZE##ptr); \ + MY_BENCHMARK3(btree_256_set_size##SIZE##copies##SIZE##ptr); \ + MY_BENCHMARK3(stl_map_size##SIZE##copies##SIZE##ptr); \ + MY_BENCHMARK3(stl_unordered_map_size##SIZE##copies##SIZE##ptr); \ + MY_BENCHMARK3(flat_hash_map_size##SIZE##copies##SIZE##ptr); \ + MY_BENCHMARK3(btree_256_map_size##SIZE##copies##SIZE##ptr) + +BIG_TYPE_PTR_BENCHMARKS(32); + +} // namespace +} // namespace container_internal +ABSL_NAMESPACE_END +} // namespace absl diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index b1c686ed..0d3d604c 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -625,7 +625,7 @@ class raw_hash_set { // PRECONDITION: not an end() iterator. iterator& operator++() { - /* To be enabled: assert_is_full(); */ + assert_is_full(); ++ctrl_; ++slot_; skip_empty_or_deleted(); @@ -1084,10 +1084,15 @@ class raw_hash_set { // Extension API: support for lazy emplace. // // Looks up key in the table. If found, returns the iterator to the element. - // Otherwise calls f with one argument of type raw_hash_set::constructor. f - // MUST call raw_hash_set::constructor with arguments as if a - // raw_hash_set::value_type is constructed, otherwise the behavior is - // undefined. + // Otherwise calls `f` with one argument of type `raw_hash_set::constructor`. + // + // `f` must abide by several restrictions: + // - it MUST call `raw_hash_set::constructor` with arguments as if a + // `raw_hash_set::value_type` is constructed, + // - it MUST NOT access the container before the call to + // `raw_hash_set::constructor`, and + // - it MUST NOT erase the lazily emplaced element. + // Doing any of these is undefined behavior. // // For example: // diff --git a/absl/flags/marshalling.h b/absl/flags/marshalling.h index 1f3dc2dc..0b503354 100644 --- a/absl/flags/marshalling.h +++ b/absl/flags/marshalling.h @@ -33,16 +33,16 @@ // * `double` // * `std::string` // * `std::vector` -// * `absl::LogSeverity` (provided here due to dependency ordering) +// * `absl::LogSeverity` (provided natively for layering reasons) // // Note that support for integral types is implemented using overloads for // variable-width fundamental types (`short`, `int`, `long`, etc.). However, // you should prefer the fixed-width integral types (`int32_t`, `uint64_t`, // etc.) we've noted above within flag definitions. - // // In addition, several Abseil libraries provide their own custom support for -// Abseil flags. +// Abseil flags. Documentation for these formats is provided in the type's +// `AbslParseFlag()` definition. // // The Abseil time library provides the following support for civil time values: // diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index 5726ea5c..51d7dd6f 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h @@ -27,9 +27,6 @@ namespace absl { ABSL_NAMESPACE_BEGIN - -class Cord; - namespace str_format_internal { class FormatRawSinkImpl { diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index caab4631..a0e5a7fd 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc @@ -30,6 +30,7 @@ #include #include +#include "absl/base/attributes.h" #include "absl/base/internal/bits.h" #include "absl/base/internal/raw_logging.h" #include "absl/strings/ascii.h" @@ -719,8 +720,8 @@ inline bool safe_parse_sign_and_base(absl::string_view* text /*inout*/, // commonly used bases. template struct LookupTables { - static const IntType kVmaxOverBase[]; - static const IntType kVminOverBase[]; + ABSL_CONST_INIT static const IntType kVmaxOverBase[]; + ABSL_CONST_INIT static const IntType kVminOverBase[]; }; // An array initializer macro for X/base where base in [0, 36]. @@ -735,6 +736,49 @@ struct LookupTables { X / 35, X / 36, \ } +// uint128& operator/=(uint128) is not constexpr, so hardcode the resulting +// array to avoid a static initializer. +template <> +const uint128 LookupTables::kVmaxOverBase[] = { + 0, + 0, + MakeUint128(9223372036854775807u, 18446744073709551615u), + MakeUint128(6148914691236517205u, 6148914691236517205u), + MakeUint128(4611686018427387903u, 18446744073709551615u), + MakeUint128(3689348814741910323u, 3689348814741910323u), + MakeUint128(3074457345618258602u, 12297829382473034410u), + MakeUint128(2635249153387078802u, 5270498306774157604u), + MakeUint128(2305843009213693951u, 18446744073709551615u), + MakeUint128(2049638230412172401u, 14347467612885206812u), + MakeUint128(1844674407370955161u, 11068046444225730969u), + MakeUint128(1676976733973595601u, 8384883669867978007u), + MakeUint128(1537228672809129301u, 6148914691236517205u), + MakeUint128(1418980313362273201u, 4256940940086819603u), + MakeUint128(1317624576693539401u, 2635249153387078802u), + MakeUint128(1229782938247303441u, 1229782938247303441u), + MakeUint128(1152921504606846975u, 18446744073709551615u), + MakeUint128(1085102592571150095u, 1085102592571150095u), + MakeUint128(1024819115206086200u, 16397105843297379214u), + MakeUint128(970881267037344821u, 16504981539634861972u), + MakeUint128(922337203685477580u, 14757395258967641292u), + MakeUint128(878416384462359600u, 14054662151397753612u), + MakeUint128(838488366986797800u, 13415813871788764811u), + MakeUint128(802032351030850070u, 4812194106185100421u), + MakeUint128(768614336404564650u, 12297829382473034410u), + MakeUint128(737869762948382064u, 11805916207174113034u), + MakeUint128(709490156681136600u, 11351842506898185609u), + MakeUint128(683212743470724133u, 17080318586768103348u), + MakeUint128(658812288346769700u, 10540996613548315209u), + MakeUint128(636094623231363848u, 15266270957552732371u), + MakeUint128(614891469123651720u, 9838263505978427528u), + MakeUint128(595056260442243600u, 9520900167075897608u), + MakeUint128(576460752303423487u, 18446744073709551615u), + MakeUint128(558992244657865200u, 8943875914525843207u), + MakeUint128(542551296285575047u, 9765923333140350855u), + MakeUint128(527049830677415760u, 8432797290838652167u), + MakeUint128(512409557603043100u, 8198552921648689607u), +}; + template const IntType LookupTables::kVmaxOverBase[] = X_OVER_BASE_INITIALIZER(std::numeric_limits::max()); @@ -754,6 +798,8 @@ inline bool safe_parse_positive_int(absl::string_view text, int base, assert(base >= 0); assert(vmax >= static_cast(base)); const IntType vmax_over_base = LookupTables::kVmaxOverBase[base]; + assert(base < 2 || + std::numeric_limits::max() / base == vmax_over_base); const char* start = text.data(); const char* end = start + text.size(); // loop over digits @@ -787,6 +833,8 @@ inline bool safe_parse_negative_int(absl::string_view text, int base, assert(vmin < 0); assert(vmin <= 0 - base); IntType vmin_over_base = LookupTables::kVminOverBase[base]; + assert(base < 2 || + std::numeric_limits::min() / base == vmin_over_base); // 2003 c++ standard [expr.mul] // "... the sign of the remainder is implementation-defined." // Although (vmin/base)*base + vmin%base is always vmin. diff --git a/absl/time/internal/cctz/src/zone_info_source.cc b/absl/time/internal/cctz/src/zone_info_source.cc index 619ac1fb..98ea1612 100644 --- a/absl/time/internal/cctz/src/zone_info_source.cc +++ b/absl/time/internal/cctz/src/zone_info_source.cc @@ -66,13 +66,41 @@ extern ZoneInfoSourceFactory zone_info_source_factory; extern ZoneInfoSourceFactory default_factory; ZoneInfoSourceFactory default_factory = DefaultFactory; #if defined(_M_IX86) -#pragma comment( \ - linker, \ - "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZA=?default_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZA") +#pragma comment( \ + linker, \ + "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@@ZA=?default_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@@ZA") #elif defined(_M_IA_64) || defined(_M_AMD64) || defined(_M_ARM64) -#pragma comment( \ - linker, \ - "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZEA=?default_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZEA") +#pragma comment( \ + linker, \ + "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@@ZEA=?default_factory@cctz_extension@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@U?$default_delete@VZoneInfoSource@cctz@time_internal@" ABSL_INTERNAL_MANGLED_NS \ + "@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@" ABSL_INTERNAL_MANGLED_BACKREFERENCE \ + "@@ZEA") #else #error Unsupported MSVC platform #endif // _M_ diff --git a/absl/time/time.h b/absl/time/time.h index 7507b0cd..1be5727c 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -527,30 +527,59 @@ std::chrono::seconds ToChronoSeconds(Duration d); std::chrono::minutes ToChronoMinutes(Duration d); std::chrono::hours ToChronoHours(Duration d); + // FormatDuration() // -// Returns a string representing the duration in the form "72h3m0.5s". -// Returns "inf" or "-inf" for +/- `InfiniteDuration()`. +// Returns a string represention of the duration in a format consisting of a +// possibly-signed prefix and a sequence of decimal numbers, each with an +// optional fractional part and a unit suffix. +// +// Valid unit suffixes are "ns", "us" "ms", "s", "m", and "h". +// +// Simple examples include "300ms", "-1.5h", and "2h45m". Returns "inf" or +// "-inf" for +/- `InfiniteDuration()` values and "0" for `ZeroDuration()` +// values. +// +// This string format is used both as an input for parsing (when handling +// command-line flags of type `absl::Duration`) and as an output in +// `FormatDuration()` std::string FormatDuration(Duration d); -// Output stream operator. -inline std::ostream& operator<<(std::ostream& os, Duration d) { - return os << FormatDuration(d); -} - // ParseDuration() // -// Parses a duration string consisting of a possibly signed sequence of -// decimal numbers, each with an optional fractional part and a unit -// suffix. The valid suffixes are "ns", "us" "ms", "s", "m", and "h". -// Simple examples include "300ms", "-1.5h", and "2h45m". Parses "0" as -// `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`. +// Parses a `dur_string` of the format noted above into an `absl::Duration` +// value. +// +// Parses "0" as a zero-length duration value. Parses "-inf" or "+inf" as +// infinite durations values. bool ParseDuration(const std::string& dur_string, Duration* d); -// Support for flag values of type Duration. Duration flags must be specified -// in a format that is valid input for absl::ParseDuration(). +// AbslParseFlag() +// +// Parses the command-line flag string representation `text` (using the format +// noted above) into an `absl::Duration` destination, setting `error` on +// failure. +// +// Example: +// +// --timeout=6h30m +// --timeout=inf // Equivalent to `InfiniteDuration()` +// --timeout=0 // Equivalent to `ZeroDuration()` bool AbslParseFlag(absl::string_view text, Duration* dst, std::string* error); + +// AbslUnparseFlag() +// +// Unparses an `absl::Duration` into a command-line string representation using +// the format noted above. std::string AbslUnparseFlag(Duration d); + +// operator<<() +// +// Output stream operator, returning a stream in the format noted above. +inline std::ostream& operator<<(std::ostream& os, Duration d) { + return os << FormatDuration(d); +} + ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const std::string& text, Duration* dst, std::string* error); ABSL_DEPRECATED("Use AbslUnparseFlag() instead.") @@ -813,18 +842,29 @@ Time FromChrono(const std::chrono::system_clock::time_point& tp); // // tp == std::chrono::system_clock::from_time_t(123); std::chrono::system_clock::time_point ToChronoTime(Time); -// Support for flag values of type Time. Time flags must be specified in a -// format that matches absl::RFC3339_full. For example: +// AbslParseFlag() +// +// Parses the command-line flag string representation `text` into an +// `absl::Time` destination, setting `error` on failure. Time flag string +// representations must be specified in a format that matches +// `absl::RFC3339_full`. +// +// Example: // // --start_time=2016-01-02T03:04:05.678+08:00 // // Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required. // // Additionally, if you'd like to specify a time as a count of -// seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag -// and add that duration to absl::UnixEpoch() to get an absl::Time. +// seconds/milliseconds/etc from the Unix epoch, use an `absl::Duration` flag +// and add that duration to `absl::UnixEpoch()` to get an `absl::Time`. bool AbslParseFlag(absl::string_view text, Time* t, std::string* error); + +// AbslUnparseFlag() +// +// Unparses an `absl::Time` into a command-line string format as noted above. std::string AbslUnparseFlag(Time t); + ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const std::string& text, Time* t, std::string* error); ABSL_DEPRECATED("Use AbslUnparseFlag() instead.") diff --git a/absl/types/compare.h b/absl/types/compare.h index c29ced52..62ca70f9 100644 --- a/absl/types/compare.h +++ b/absl/types/compare.h @@ -176,6 +176,14 @@ class weak_equality weak_equality v) noexcept { return 0 != v.value_; } + friend constexpr bool operator==(weak_equality v1, + weak_equality v2) noexcept { + return v1.value_ == v2.value_; + } + friend constexpr bool operator!=(weak_equality v1, + weak_equality v2) noexcept { + return v1.value_ != v2.value_; + } private: compare_internal::value_type value_; @@ -219,6 +227,14 @@ class strong_equality strong_equality v) noexcept { return 0 != v.value_; } + friend constexpr bool operator==(strong_equality v1, + strong_equality v2) noexcept { + return v1.value_ == v2.value_; + } + friend constexpr bool operator!=(strong_equality v1, + strong_equality v2) noexcept { + return v1.value_ != v2.value_; + } private: compare_internal::value_type value_; @@ -306,6 +322,14 @@ class partial_ordering partial_ordering v) noexcept { return v.is_ordered() && 0 >= v.value_; } + friend constexpr bool operator==(partial_ordering v1, + partial_ordering v2) noexcept { + return v1.value_ == v2.value_; + } + friend constexpr bool operator!=(partial_ordering v1, + partial_ordering v2) noexcept { + return v1.value_ != v2.value_; + } private: compare_internal::value_type value_; @@ -390,6 +414,14 @@ class weak_ordering weak_ordering v) noexcept { return 0 >= v.value_; } + friend constexpr bool operator==(weak_ordering v1, + weak_ordering v2) noexcept { + return v1.value_ == v2.value_; + } + friend constexpr bool operator!=(weak_ordering v1, + weak_ordering v2) noexcept { + return v1.value_ != v2.value_; + } private: compare_internal::value_type value_; @@ -481,6 +513,14 @@ class strong_ordering strong_ordering v) noexcept { return 0 >= v.value_; } + friend constexpr bool operator==(strong_ordering v1, + strong_ordering v2) noexcept { + return v1.value_ == v2.value_; + } + friend constexpr bool operator!=(strong_ordering v1, + strong_ordering v2) noexcept { + return v1.value_ != v2.value_; + } private: compare_internal::value_type value_; diff --git a/absl/types/compare_test.cc b/absl/types/compare_test.cc index 955844b5..8095baf9 100644 --- a/absl/types/compare_test.cc +++ b/absl/types/compare_test.cc @@ -31,6 +31,15 @@ TEST(Compare, WeakEquality) { EXPECT_TRUE(Identity(0 == weak_equality::equivalent)); EXPECT_TRUE(Identity(weak_equality::nonequivalent != 0)); EXPECT_TRUE(Identity(0 != weak_equality::nonequivalent)); + const weak_equality values[] = {weak_equality::equivalent, + weak_equality::nonequivalent}; + for (const auto& lhs : values) { + for (const auto& rhs : values) { + const bool are_equal = &lhs == &rhs; + EXPECT_EQ(lhs == rhs, are_equal); + EXPECT_EQ(lhs != rhs, !are_equal); + } + } } TEST(Compare, StrongEquality) { @@ -42,6 +51,18 @@ TEST(Compare, StrongEquality) { EXPECT_TRUE(Identity(0 == strong_equality::equivalent)); EXPECT_TRUE(Identity(strong_equality::nonequivalent != 0)); EXPECT_TRUE(Identity(0 != strong_equality::nonequivalent)); + const strong_equality values[] = {strong_equality::equal, + strong_equality::nonequal}; + for (const auto& lhs : values) { + for (const auto& rhs : values) { + const bool are_equal = &lhs == &rhs; + EXPECT_EQ(lhs == rhs, are_equal); + EXPECT_EQ(lhs != rhs, !are_equal); + } + } + EXPECT_TRUE(Identity(strong_equality::equivalent == strong_equality::equal)); + EXPECT_TRUE( + Identity(strong_equality::nonequivalent == strong_equality::nonequal)); } TEST(Compare, PartialOrdering) { @@ -65,6 +86,16 @@ TEST(Compare, PartialOrdering) { EXPECT_FALSE(Identity(0 > partial_ordering::unordered)); EXPECT_FALSE(Identity(partial_ordering::unordered >= 0)); EXPECT_FALSE(Identity(0 >= partial_ordering::unordered)); + const partial_ordering values[] = { + partial_ordering::less, partial_ordering::equivalent, + partial_ordering::greater, partial_ordering::unordered}; + for (const auto& lhs : values) { + for (const auto& rhs : values) { + const bool are_equal = &lhs == &rhs; + EXPECT_EQ(lhs == rhs, are_equal); + EXPECT_EQ(lhs != rhs, !are_equal); + } + } } TEST(Compare, WeakOrdering) { @@ -78,6 +109,15 @@ TEST(Compare, WeakOrdering) { EXPECT_TRUE(Identity(0 < weak_ordering::greater)); EXPECT_TRUE(Identity(weak_ordering::greater >= 0)); EXPECT_TRUE(Identity(0 <= weak_ordering::greater)); + const weak_ordering values[] = { + weak_ordering::less, weak_ordering::equivalent, weak_ordering::greater}; + for (const auto& lhs : values) { + for (const auto& rhs : values) { + const bool are_equal = &lhs == &rhs; + EXPECT_EQ(lhs == rhs, are_equal); + EXPECT_EQ(lhs != rhs, !are_equal); + } + } } TEST(Compare, StrongOrdering) { @@ -93,6 +133,16 @@ TEST(Compare, StrongOrdering) { EXPECT_TRUE(Identity(0 < strong_ordering::greater)); EXPECT_TRUE(Identity(strong_ordering::greater >= 0)); EXPECT_TRUE(Identity(0 <= strong_ordering::greater)); + const strong_ordering values[] = { + strong_ordering::less, strong_ordering::equal, strong_ordering::greater}; + for (const auto& lhs : values) { + for (const auto& rhs : values) { + const bool are_equal = &lhs == &rhs; + EXPECT_EQ(lhs == rhs, are_equal); + EXPECT_EQ(lhs != rhs, !are_equal); + } + } + EXPECT_TRUE(Identity(strong_ordering::equivalent == strong_ordering::equal)); } TEST(Compare, Conversions) { @@ -190,7 +240,7 @@ TEST(Compare, Conversions) { struct WeakOrderingLess { template - absl::weak_ordering operator()(const T &a, const T &b) const { + absl::weak_ordering operator()(const T& a, const T& b) const { return a < b ? absl::weak_ordering::less : a == b ? absl::weak_ordering::equivalent : absl::weak_ordering::greater; @@ -224,10 +274,10 @@ TEST(DoLessThanComparison, SanityTest) { } TEST(CompareResultAsOrdering, SanityTest) { - EXPECT_TRUE(Identity( - absl::compare_internal::compare_result_as_ordering(-1) < 0)); - EXPECT_FALSE(Identity( - absl::compare_internal::compare_result_as_ordering(-1) == 0)); + EXPECT_TRUE( + Identity(absl::compare_internal::compare_result_as_ordering(-1) < 0)); + EXPECT_FALSE( + Identity(absl::compare_internal::compare_result_as_ordering(-1) == 0)); EXPECT_FALSE( Identity(absl::compare_internal::compare_result_as_ordering(-1) > 0)); EXPECT_TRUE(Identity(absl::compare_internal::compare_result_as_ordering( @@ -237,31 +287,31 @@ TEST(CompareResultAsOrdering, SanityTest) { EXPECT_FALSE(Identity(absl::compare_internal::compare_result_as_ordering( weak_ordering::less) > 0)); - EXPECT_FALSE(Identity( - absl::compare_internal::compare_result_as_ordering(0) < 0)); - EXPECT_TRUE(Identity( - absl::compare_internal::compare_result_as_ordering(0) == 0)); - EXPECT_FALSE(Identity( - absl::compare_internal::compare_result_as_ordering(0) > 0)); + EXPECT_FALSE( + Identity(absl::compare_internal::compare_result_as_ordering(0) < 0)); + EXPECT_TRUE( + Identity(absl::compare_internal::compare_result_as_ordering(0) == 0)); + EXPECT_FALSE( + Identity(absl::compare_internal::compare_result_as_ordering(0) > 0)); EXPECT_FALSE(Identity(absl::compare_internal::compare_result_as_ordering( - weak_ordering::equivalent) < 0)); + weak_ordering::equivalent) < 0)); EXPECT_TRUE(Identity(absl::compare_internal::compare_result_as_ordering( - weak_ordering::equivalent) == 0)); + weak_ordering::equivalent) == 0)); EXPECT_FALSE(Identity(absl::compare_internal::compare_result_as_ordering( weak_ordering::equivalent) > 0)); - EXPECT_FALSE(Identity( - absl::compare_internal::compare_result_as_ordering(1) < 0)); - EXPECT_FALSE(Identity( - absl::compare_internal::compare_result_as_ordering(1) == 0)); - EXPECT_TRUE(Identity( - absl::compare_internal::compare_result_as_ordering(1) > 0)); + EXPECT_FALSE( + Identity(absl::compare_internal::compare_result_as_ordering(1) < 0)); + EXPECT_FALSE( + Identity(absl::compare_internal::compare_result_as_ordering(1) == 0)); + EXPECT_TRUE( + Identity(absl::compare_internal::compare_result_as_ordering(1) > 0)); EXPECT_FALSE(Identity(absl::compare_internal::compare_result_as_ordering( - weak_ordering::greater) < 0)); + weak_ordering::greater) < 0)); EXPECT_FALSE(Identity(absl::compare_internal::compare_result_as_ordering( weak_ordering::greater) == 0)); EXPECT_TRUE(Identity(absl::compare_internal::compare_result_as_ordering( - weak_ordering::greater) > 0)); + weak_ordering::greater) > 0)); } TEST(DoThreeWayComparison, SanityTest) { -- cgit v1.2.3 From 37dd2562ec830d547a1524bb306be313ac3f2556 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 28 Jan 2020 11:50:11 -0800 Subject: Export of internal Abseil changes -- 8bdb2020150ed0fd4a4e520e454dc5f54e33f776 by Eric Fiselier : Workaround bug in GCC 9.2 and after. PiperOrigin-RevId: 291982551 -- 47ff4820e595f96c082a90d733725f6882d83e3b by Abseil Team : Improve ABSL_ATTRIBUTE_PACKED documentation Recommend to apply ABSL_ATTRIBUTE_PACKED to structure members instead of to an entire structure because applying this attribute to an entire structure may cause the compiler to generate suboptimal code. It reduces the alignment of the data structure from a value larger than one to one. When applied to a structure, ABSL_ATTRIBUTE_PACKED reduces the alignment of a structure (alignof()) to 1. As a result, the compiler can no longer assume that e.g. uint32 members are aligned on a four byte boundary and hence is forced to use single-byte load and store instructions on CPU architectures that do not support non-aligned loads or stores. PiperOrigin-RevId: 291977920 -- 902b7a86f860da699d3a2e5c738be5ef73ede3b4 by Mark Barolak : Internal change PiperOrigin-RevId: 291963048 -- bb3bd3247e376d53a3080b105f13ec7566d3ae50 by Abseil Team : Support the C++17 insert_or_assign() API in btree_map. PiperOrigin-RevId: 291945474 -- ff3b3cfcbbc64f086f95501f48d49426bcde356f by Gennadiy Rozental : Import of CCTZ from GitHub. PiperOrigin-RevId: 291861110 -- fd465cd9cbbacd3962f67a7346d6462edaddd809 by Derek Mauro : Add flaky=1 to beta_distribution_test. PiperOrigin-RevId: 291757364 -- 3603adfb59c4128c542b670952cce250d59e1f67 by Derek Mauro : Separate the initialization of NumCPUs() and NominalCPUFrequency() The OSS version of Abseil never needs to call NominalCPUFrequency(). In some configurations, initializing NominalCPUFrequency() requires spending at least 3ms measuring the CPU frequency. By separating the initialization from NumCPUs(), which is called in most configurations, we can save at least 3ms of program startup time. PiperOrigin-RevId: 291737273 -- bea9e4a6bff5a0351d340deab966641867e08c4d by Abseil Team : Change the cmake library names not to have a redundant `absl_` prefix. PiperOrigin-RevId: 291640501 -- 501b602ef260cd7c8c527342581ceffb3c5b6d4c by Gennadiy Rozental : Introducing benchmark for absl::GetFlag. PiperOrigin-RevId: 291433394 -- 4eeaddc788da4b91c272a8adca77ca6dbbbc1d44 by Xiaoyi Zhang : fix: Add support for more ARM processors detection Import of https://github.com/abseil/abseil-cpp/pull/608 PiperOrigin-RevId: 291420397 -- a3087a8e883c5d71de7d9bd4ec8f4db5142dfcf5 by Derek Mauro : Removes the flaky raw_hash_set prefetch test PiperOrigin-RevId: 291197079 -- aad6c2121c102ac36216e771c83227cf3e3bfd66 by Andy Soffer : Enable building Abseil as a DLL. This is currently experimental and unsupported. This CL does a few things: 1. Adds the ABSL_DLL macro to any class holding a static data member, or to global constants in headers. 2. Adds a whitelist of all files in the DLL and all the build targets that are conglomerated into the DLL. 3. When BUILD_SHARED_LIBS is specified, any build target that would be in the DLL still exists, but we swap out all of it's dependencies so it just depends on abseil_dll PiperOrigin-RevId: 291192055 -- 5e888cd6f2a7722805d41f872108a03a84e421c7 by Mark Barolak : Move absl/strings/internal/escaping.{cc,h} into internal build targets. This puts absl/strings/internal/escaping.h behind a whitelist and it also resolves https://github.com/abseil/abseil-cpp/issues/604. PiperOrigin-RevId: 291173320 -- 166836d24970da87587c1728036f53f05a28f0af by Eric Fiselier : Internal Change. PiperOrigin-RevId: 291012718 -- 996ddb3dffda02440fa93f30ca5d71b14b688875 by Abseil Team : Fix shared libraries log spam for built-in types in absl::GetFlag PiperOrigin-RevId: 290772743 GitOrigin-RevId: 8bdb2020150ed0fd4a4e520e454dc5f54e33f776 Change-Id: I8bf2265dd14ebbace220a1b6b982bb5040ad2a26 --- CMake/AbseilDll.cmake | 492 +++++++++++++++++++++ CMake/AbseilHelpers.cmake | 231 +++++++--- CMake/Googletest/DownloadGTest.cmake | 10 + CMakeLists.txt | 7 + absl/CMakeLists.txt | 6 +- absl/base/attributes.h | 14 +- absl/base/config.h | 19 + absl/base/internal/raw_logging.cc | 5 +- absl/base/internal/raw_logging.h | 5 +- absl/base/internal/sysinfo.cc | 28 +- absl/base/internal/thread_identity.cc | 12 + absl/base/internal/thread_identity.h | 9 + absl/base/options.h | 9 +- absl/container/btree_map.h | 24 + absl/container/btree_test.cc | 59 +++ absl/container/internal/btree_container.h | 65 ++- absl/container/internal/hashtablez_sampler.cc | 9 +- absl/container/internal/hashtablez_sampler.h | 13 +- absl/container/internal/hashtablez_sampler_test.cc | 2 +- absl/container/internal/raw_hash_set_test.cc | 51 +-- absl/copts/AbseilConfigureCopts.cmake | 7 + absl/debugging/symbolize_test.cc | 2 + absl/flags/BUILD.bazel | 17 + absl/flags/flag.cc | 9 +- absl/flags/flag.h | 24 +- absl/flags/flag_benchmark.cc | 111 +++++ absl/hash/internal/hash.h | 3 +- absl/numeric/int128.cc | 4 +- absl/numeric/int128.h | 2 +- absl/random/BUILD.bazel | 2 + absl/random/CMakeLists.txt | 1 + absl/random/gaussian_distribution.h | 3 +- absl/strings/BUILD.bazel | 5 +- absl/strings/CMakeLists.txt | 5 +- absl/strings/ascii.cc | 6 +- absl/strings/ascii.h | 7 +- absl/strings/internal/charconv_bigint.cc | 4 +- absl/strings/internal/charconv_bigint.h | 6 +- absl/strings/internal/str_format/bind.h | 4 +- absl/strings/internal/str_format/extension.h | 6 +- absl/strings/numbers.cc | 7 +- absl/strings/numbers.h | 9 +- absl/strings/string_view.h | 25 +- absl/time/format.cc | 13 +- absl/time/internal/cctz/src/time_zone_fixed.cc | 28 +- .../internal/cctz/src/time_zone_format_test.cc | 4 +- absl/time/internal/cctz/src/time_zone_info.cc | 6 +- .../internal/cctz/src/time_zone_lookup_test.cc | 15 +- absl/time/time.h | 87 ++-- 49 files changed, 1197 insertions(+), 295 deletions(-) create mode 100644 CMake/AbseilDll.cmake create mode 100644 absl/flags/flag_benchmark.cc (limited to 'absl/base/config.h') diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake new file mode 100644 index 00000000..8184d500 --- /dev/null +++ b/CMake/AbseilDll.cmake @@ -0,0 +1,492 @@ +include(CMakeParseArguments) + +set(ABSL_INTERNAL_DLL_FILES + "algorithm/algorithm.h" + "algorithm/container.h" + "base/attributes.h" + "base/call_once.h" + "base/casts.h" + "base/config.h" + "base/const_init.h" + "base/dynamic_annotations.cc" + "base/dynamic_annotations.h" + "base/internal/atomic_hook.h" + "base/internal/bits.h" + "base/internal/cycleclock.cc" + "base/internal/cycleclock.h" + "base/internal/direct_mmap.h" + "base/internal/endian.h" + "base/internal/exponential_biased.cc" + "base/internal/exponential_biased.h" + "base/internal/hide_ptr.h" + "base/internal/identity.h" + "base/internal/invoke.h" + "base/internal/inline_variable.h" + "base/internal/low_level_alloc.cc" + "base/internal/low_level_alloc.h" + "base/internal/low_level_scheduling.h" + "base/internal/per_thread_tls.h" + "base/internal/periodic_sampler.cc" + "base/internal/periodic_sampler.h" + "base/internal/pretty_function.h" + "base/internal/raw_logging.cc" + "base/internal/raw_logging.h" + "base/internal/scheduling_mode.h" + "base/internal/scoped_set_env.cc" + "base/internal/scoped_set_env.h" + "base/internal/spinlock.cc" + "base/internal/spinlock.h" + "base/internal/spinlock_wait.cc" + "base/internal/spinlock_wait.h" + "base/internal/sysinfo.cc" + "base/internal/sysinfo.h" + "base/internal/thread_annotations.h" + "base/internal/thread_identity.cc" + "base/internal/thread_identity.h" + "base/internal/throw_delegate.cc" + "base/internal/throw_delegate.h" + "base/internal/tsan_mutex_interface.h" + "base/internal/unaligned_access.h" + "base/internal/unscaledcycleclock.cc" + "base/internal/unscaledcycleclock.h" + "base/log_severity.cc" + "base/log_severity.h" + "base/macros.h" + "base/optimization.h" + "base/options.h" + "base/policy_checks.h" + "base/port.h" + "base/thread_annotations.h" + "container/btree_map.h" + "container/btree_set.h" + "container/fixed_array.h" + "container/flat_hash_map.h" + "container/flat_hash_set.h" + "container/inlined_vector.h" + "container/internal/btree.h" + "container/internal/btree_container.h" + "container/internal/common.h" + "container/internal/compressed_tuple.h" + "container/internal/container_memory.h" + "container/internal/counting_allocator.h" + "container/internal/hash_function_defaults.h" + "container/internal/hash_policy_traits.h" + "container/internal/hashtable_debug.h" + "container/internal/hashtable_debug_hooks.h" + "container/internal/hashtablez_sampler.cc" + "container/internal/hashtablez_sampler.h" + "container/internal/hashtablez_sampler_force_weak_definition.cc" + "container/internal/have_sse.h" + "container/internal/inlined_vector.h" + "container/internal/layout.h" + "container/internal/node_hash_policy.h" + "container/internal/raw_hash_map.h" + "container/internal/raw_hash_set.cc" + "container/internal/raw_hash_set.h" + "container/internal/tracked.h" + "container/node_hash_map.h" + "container/node_hash_set.h" + "debugging/failure_signal_handler.cc" + "debugging/failure_signal_handler.h" + "debugging/leak_check.h" + "debugging/leak_check_disable.cc" + "debugging/stacktrace.cc" + "debugging/stacktrace.h" + "debugging/symbolize.cc" + "debugging/symbolize.h" + "debugging/internal/address_is_readable.cc" + "debugging/internal/address_is_readable.h" + "debugging/internal/demangle.cc" + "debugging/internal/demangle.h" + "debugging/internal/elf_mem_image.cc" + "debugging/internal/elf_mem_image.h" + "debugging/internal/examine_stack.cc" + "debugging/internal/examine_stack.h" + "debugging/internal/stack_consumption.cc" + "debugging/internal/stack_consumption.h" + "debugging/internal/stacktrace_config.h" + "debugging/internal/symbolize.h" + "debugging/internal/vdso_support.cc" + "debugging/internal/vdso_support.h" + "functional/function_ref.h" + "functional/internal/function_ref.h" + "hash/hash.h" + "hash/internal/city.h" + "hash/internal/city.cc" + "hash/internal/hash.h" + "hash/internal/hash.cc" + "hash/internal/spy_hash_state.h" + "memory/memory.h" + "meta/type_traits.h" + "numeric/int128.cc" + "numeric/int128.h" + "random/bernoulli_distribution.h" + "random/beta_distribution.h" + "random/bit_gen_ref.h" + "random/discrete_distribution.cc" + "random/discrete_distribution.h" + "random/distribution_format_traits.h" + "random/distributions.h" + "random/exponential_distribution.h" + "random/gaussian_distribution.cc" + "random/gaussian_distribution.h" + "random/internal/distributions.h" + "random/internal/distribution_caller.h" + "random/internal/fast_uniform_bits.h" + "random/internal/fastmath.h" + "random/internal/gaussian_distribution_gentables.cc" + "random/internal/generate_real.h" + "random/internal/iostream_state_saver.h" + "random/internal/nonsecure_base.h" + "random/internal/pcg_engine.h" + "random/internal/platform.h" + "random/internal/pool_urbg.cc" + "random/internal/pool_urbg.h" + "random/internal/randen.cc" + "random/internal/randen.h" + "random/internal/randen_detect.cc" + "random/internal/randen_detect.h" + "random/internal/randen_engine.h" + "random/internal/randen_hwaes.cc" + "random/internal/randen_hwaes.h" + "random/internal/randen_slow.cc" + "random/internal/randen_slow.h" + "random/internal/randen_traits.h" + "random/internal/salted_seed_seq.h" + "random/internal/seed_material.cc" + "random/internal/seed_material.h" + "random/internal/sequence_urbg.h" + "random/internal/traits.h" + "random/internal/uniform_helper.h" + "random/internal/wide_multiply.h" + "random/log_uniform_int_distribution.h" + "random/poisson_distribution.h" + "random/random.h" + "random/seed_gen_exception.cc" + "random/seed_gen_exception.h" + "random/seed_sequences.cc" + "random/seed_sequences.h" + "random/uniform_int_distribution.h" + "random/uniform_real_distribution.h" + "random/zipf_distribution.h" + "strings/ascii.cc" + "strings/ascii.h" + "strings/charconv.cc" + "strings/charconv.h" + "strings/escaping.cc" + "strings/escaping.h" + "strings/internal/charconv_bigint.cc" + "strings/internal/charconv_bigint.h" + "strings/internal/charconv_parse.cc" + "strings/internal/charconv_parse.h" + "strings/internal/escaping.cc" + "strings/internal/escaping.h" + "strings/internal/stl_type_traits.h" + "strings/match.cc" + "strings/match.h" + "strings/numbers.cc" + "strings/numbers.h" + "strings/str_format.h" + "strings/str_cat.cc" + "strings/str_cat.h" + "strings/str_join.h" + "strings/str_replace.cc" + "strings/str_replace.h" + "strings/str_split.cc" + "strings/str_split.h" + "strings/string_view.cc" + "strings/string_view.h" + "strings/strip.h" + "strings/substitute.cc" + "strings/substitute.h" + "strings/internal/char_map.h" + "strings/internal/memutil.cc" + "strings/internal/memutil.h" + "strings/internal/ostringstream.cc" + "strings/internal/ostringstream.h" + "strings/internal/pow10_helper.cc" + "strings/internal/pow10_helper.h" + "strings/internal/resize_uninitialized.h" + "strings/internal/str_format/arg.cc" + "strings/internal/str_format/arg.h" + "strings/internal/str_format/bind.cc" + "strings/internal/str_format/bind.h" + "strings/internal/str_format/checker.h" + "strings/internal/str_format/extension.cc" + "strings/internal/str_format/extension.h" + "strings/internal/str_format/float_conversion.cc" + "strings/internal/str_format/float_conversion.h" + "strings/internal/str_format/output.cc" + "strings/internal/str_format/output.h" + "strings/internal/str_format/parser.cc" + "strings/internal/str_format/parser.h" + "strings/internal/str_join_internal.h" + "strings/internal/str_split_internal.h" + "strings/internal/utf8.cc" + "strings/internal/utf8.h" + "synchronization/barrier.cc" + "synchronization/barrier.h" + "synchronization/blocking_counter.cc" + "synchronization/blocking_counter.h" + "synchronization/mutex.cc" + "synchronization/mutex.h" + "synchronization/notification.cc" + "synchronization/notification.h" + "synchronization/internal/create_thread_identity.cc" + "synchronization/internal/create_thread_identity.h" + "synchronization/internal/graphcycles.cc" + "synchronization/internal/graphcycles.h" + "synchronization/internal/kernel_timeout.h" + "synchronization/internal/per_thread_sem.cc" + "synchronization/internal/per_thread_sem.h" + "synchronization/internal/thread_pool.h" + "synchronization/internal/waiter.cc" + "synchronization/internal/waiter.h" + "time/civil_time.cc" + "time/civil_time.h" + "time/clock.cc" + "time/clock.h" + "time/duration.cc" + "time/format.cc" + "time/time.cc" + "time/time.h" + "time/internal/cctz/include/cctz/civil_time.h" + "time/internal/cctz/include/cctz/civil_time_detail.h" + "time/internal/cctz/include/cctz/time_zone.h" + "time/internal/cctz/include/cctz/zone_info_source.h" + "time/internal/cctz/src/civil_time_detail.cc" + "time/internal/cctz/src/time_zone_fixed.cc" + "time/internal/cctz/src/time_zone_fixed.h" + "time/internal/cctz/src/time_zone_format.cc" + "time/internal/cctz/src/time_zone_if.cc" + "time/internal/cctz/src/time_zone_if.h" + "time/internal/cctz/src/time_zone_impl.cc" + "time/internal/cctz/src/time_zone_impl.h" + "time/internal/cctz/src/time_zone_info.cc" + "time/internal/cctz/src/time_zone_info.h" + "time/internal/cctz/src/time_zone_libc.cc" + "time/internal/cctz/src/time_zone_libc.h" + "time/internal/cctz/src/time_zone_lookup.cc" + "time/internal/cctz/src/time_zone_posix.cc" + "time/internal/cctz/src/time_zone_posix.h" + "time/internal/cctz/src/tzfile.h" + "time/internal/cctz/src/zone_info_source.cc" + "types/any.h" + "types/bad_any_cast.cc" + "types/bad_any_cast.h" + "types/bad_optional_access.cc" + "types/bad_optional_access.h" + "types/bad_variant_access.cc" + "types/bad_variant_access.h" + "types/compare.h" + "types/internal/conformance_aliases.h" + "types/internal/conformance_archetype.h" + "types/internal/conformance_profile.h" + "types/internal/variant.h" + "types/optional.h" + "types/internal/optional.h" + "types/span.h" + "types/internal/span.h" + "types/variant.h" + "utility/utility.h" +) + +set(ABSL_INTERNAL_DLL_TARGETS + "stacktrace" + "symbolize" + "examine_stack" + "failure_signal_handler" + "debugging_internal" + "demangle_internal" + "leak_check" + "leak_check_disable" + "stack_consumption" + "debugging" + "hash" + "spy_hash_state" + "city" + "memory" + "strings" + "strings_internal" + "str_format" + "str_format_internal" + "pow10_helper" + "int128" + "numeric" + "utility" + "any" + "bad_any_cast" + "bad_any_cast_impl" + "span" + "optional" + "bad_optional_access" + "bad_variant_access" + "variant" + "compare" + "algorithm" + "algorithm_container" + "graphcycles_internal" + "kernel_timeout_internal" + "synchronization" + "thread_pool" + "bind_front" + "function_ref" + "atomic_hook" + "log_severity" + "raw_logging_internal" + "spinlock_wait" + "config" + "dynamic_annotations" + "core_headers" + "malloc_internal" + "base_internal" + "base" + "throw_delegate" + "pretty_function" + "endian" + "bits" + "exponential_biased" + "periodic_sampler" + "scoped_set_env" + "type_traits" + "meta" + "random_random" + "random_bit_gen_ref" + "random_distributions" + "random_seed_gen_exception" + "random_seed_sequences" + "random_internal_traits" + "random_internal_distribution_caller" + "random_internal_distributions" + "random_internal_fast_uniform_bits" + "random_internal_seed_material" + "random_internal_pool_urbg" + "random_internal_explicit_seed_seq" + "random_internal_sequence_urbg" + "random_internal_salted_seed_seq" + "random_internal_iostream_state_saver" + "random_internal_generate_real" + "random_internal_wide_multiply" + "random_internal_fastmath" + "random_internal_nonsecure_base" + "random_internal_pcg_engine" + "random_internal_randen_engine" + "random_internal_platform" + "random_internal_randen" + "random_internal_randen_slow" + "random_internal_randen_hwaes" + "random_internal_randen_hwaes_impl" + "random_internal_uniform_helper" + "time" + "civil_time" + "time_zone" + "container" + "btree" + "compressed_tuple" + "fixed_array" + "inlined_vector_internal" + "inlined_vector" + "counting_allocator" + "flat_hash_map" + "flat_hash_set" + "node_hash_map" + "node_hash_set" + "container_memory" + "hash_function_defaults" + "hash_policy_traits" + "hashtablez_sampler" + "hashtable_debug" + "hashtable_debug_hooks" + "have_sse" + "node_hash_policy" + "raw_hash_map" + "container_common" + "raw_hash_set" + "layout" + "tracked" +) + +function(absl_internal_dll_contains) + cmake_parse_arguments(ABSL_INTERNAL_DLL + "" + "OUTPUT;TARGET" + "" + ${ARGN} + ) + + STRING(REGEX REPLACE "^absl::" "" _target ${ABSL_INTERNAL_DLL_TARGET}) + + list(FIND + ABSL_INTERNAL_DLL_TARGETS + "${_target}" + _index) + + if (${_index} GREATER -1) + set(${ABSL_INTERNAL_DLL_OUTPUT} 1 PARENT_SCOPE) + else() + set(${ABSL_INTERNAL_DLL_OUTPUT} 0 PARENT_SCOPE) + endif() +endfunction() + +function(absl_internal_dll_targets) + cmake_parse_arguments(ABSL_INTERNAL_DLL + "" + "OUTPUT" + "DEPS" + ${ARGN} + ) + + set(_deps "") + foreach(dep IN LISTS ABSL_INTERNAL_DLL_DEPS) + absl_internal_dll_contains(TARGET ${dep} OUTPUT _contains) + if (_contains) + list(APPEND _deps abseil_dll) + else() + list(APPEND _deps ${dep}) + endif() + endforeach() + + # Because we may have added the DLL multiple times + list(REMOVE_DUPLICATES _deps) + set(${ABSL_INTERNAL_DLL_OUTPUT} "${_deps}" PARENT_SCOPE) +endfunction() + +function(absl_make_dll) + add_library( + abseil_dll + SHARED + "${ABSL_INTERNAL_DLL_FILES}" + ) + target_link_libraries( + abseil_dll + PRIVATE + ${ABSL_DEFAULT_LINKOPTS} + ) + set_property(TARGET abseil_dll PROPERTY LINKER_LANGUAGE "CXX") + target_include_directories( + abseil_dll + PUBLIC + "$" + $ + ) + + target_compile_options( + abseil_dll + PRIVATE + ${ABSL_DEFAULT_COPTS} + ) + + target_compile_definitions( + abseil_dll + PRIVATE + ABSL_BUILD_DLL + NOMINMAX + INTERFACE + ${ABSL_CC_LIB_DEFINES} + ) + install(TARGETS abseil_dll EXPORT ${PROJECT_NAME}Targets + RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR} + LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR} + ) +endfunction() diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake index 28fefaa6..7571ef1b 100644 --- a/CMake/AbseilHelpers.cmake +++ b/CMake/AbseilHelpers.cmake @@ -16,6 +16,7 @@ include(CMakeParseArguments) include(AbseilConfigureCopts) +include(AbseilDll) include(AbseilInstallDirs) # The IDE folder for Abseil that will be used if Abseil is included in a CMake @@ -80,98 +81,169 @@ function(absl_cc_library) ${ARGN} ) - if(NOT ABSL_CC_LIB_TESTONLY OR ABSL_RUN_TESTS) - if(ABSL_ENABLE_INSTALL) - set(_NAME "${ABSL_CC_LIB_NAME}") - else() - set(_NAME "absl_${ABSL_CC_LIB_NAME}") + if(ABSL_CC_LIB_TESTONLY AND NOT ABSL_RUN_TESTS) + return() + endif() + + if(ABSL_ENABLE_INSTALL) + set(_NAME "${ABSL_CC_LIB_NAME}") + else() + set(_NAME "absl_${ABSL_CC_LIB_NAME}") + endif() + + # Check if this is a header-only library + # Note that as of February 2019, many popular OS's (for example, Ubuntu + # 16.04 LTS) only come with cmake 3.5 by default. For this reason, we can't + # use list(FILTER...) + set(ABSL_CC_SRCS "${ABSL_CC_LIB_SRCS}") + foreach(src_file IN LISTS ABSL_CC_SRCS) + if(${src_file} MATCHES ".*\\.(h|inc)") + list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}") endif() + endforeach() - # Check if this is a header-only library - # Note that as of February 2019, many popular OS's (for example, Ubuntu - # 16.04 LTS) only come with cmake 3.5 by default. For this reason, we can't - # use list(FILTER...) - set(ABSL_CC_SRCS "${ABSL_CC_LIB_SRCS}") - foreach(src_file IN LISTS ABSL_CC_SRCS) - if(${src_file} MATCHES ".*\\.(h|inc)") - list(REMOVE_ITEM ABSL_CC_SRCS "${src_file}") - endif() - endforeach() - if("${ABSL_CC_SRCS}" STREQUAL "") + if("${ABSL_CC_SRCS}" STREQUAL "") + set(ABSL_CC_LIB_IS_INTERFACE 1) + else() + set(ABSL_CC_LIB_IS_INTERFACE 0) + endif() + + # Determine this build target's relationship to the DLL. It's one of three things: + # 1. "dll" -- This target is part of the DLL + # 2. "dll_dep" -- This target is not part of the DLL, but depends on the DLL. + # Note that we assume any target not in the DLL depends on the + # DLL. This is not a technical necessity but a convenience + # which happens to be true, because nearly every target is + # part of the DLL. + # 3. "static" -- This target does not depend on the DLL and should be built + # statically. + if (${ABSL_BUILD_DLL}) + absl_internal_dll_contains(TARGET ${_NAME} OUTPUT _in_dll) + if (${_in_dll}) + # This target should be replaced by the DLL + set(_build_type "dll") set(ABSL_CC_LIB_IS_INTERFACE 1) else() - set(ABSL_CC_LIB_IS_INTERFACE 0) + # Building a DLL, but this target is not part of the DLL + set(_build_type "dll_dep") endif() + else() + set(_build_type "static") + endif() - if(NOT ABSL_CC_LIB_IS_INTERFACE) - # CMake creates static libraries by default. Users can specify - # -DBUILD_SHARED_LIBS=ON during initial configuration to build shared - # libraries instead. - add_library(${_NAME} "") + if(NOT ABSL_CC_LIB_IS_INTERFACE) + if(${_build_type} STREQUAL "dll_dep") + # This target depends on the DLL. When adding dependencies to this target, + # any depended-on-target which is contained inside the DLL is replaced + # with a dependency on the DLL. + add_library(${_NAME} STATIC "") target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS}) - target_include_directories(${_NAME} - PUBLIC - "$" - $ + absl_internal_dll_targets( + DEPS ${ABSL_CC_LIB_DEPS} + OUTPUT _dll_deps ) - target_compile_options(${_NAME} - PRIVATE ${ABSL_CC_LIB_COPTS}) target_link_libraries(${_NAME} - PUBLIC ${ABSL_CC_LIB_DEPS} + PUBLIC ${_dll_deps} PRIVATE ${ABSL_CC_LIB_LINKOPTS} ${ABSL_DEFAULT_LINKOPTS} ) - target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES}) - # Add all Abseil targets to a a folder in the IDE for organization. - if(ABSL_CC_LIB_PUBLIC) - set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) - elseif(ABSL_CC_LIB_TESTONLY) - set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test) + if (ABSL_CC_LIB_TESTONLY) + set(_gtest_link_define "GTEST_LINKED_AS_SHARED_LIBRARY=1") else() - set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/internal) + set(_gtest_link_define) endif() - # INTERFACE libraries can't have the CXX_STANDARD property set - set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) - set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) - - # When being installed, we lose the absl_ prefix. We want to put it back - # to have properly named lib files. This is a no-op when we are not being - # installed. - set_target_properties(${_NAME} PROPERTIES - OUTPUT_NAME "absl_${_NAME}" + target_compile_definitions(${_NAME} + PUBLIC + ABSL_CONSUME_DLL + "${_gtest_link_define}" ) - else() - # Generating header-only library - add_library(${_NAME} INTERFACE) - target_include_directories(${_NAME} - INTERFACE - "$" - $ - ) + + elseif(${_build_type} STREQUAL "static") + add_library(${_NAME} STATIC "") + target_sources(${_NAME} PRIVATE ${ABSL_CC_LIB_SRCS} ${ABSL_CC_LIB_HDRS}) target_link_libraries(${_NAME} - INTERFACE - ${ABSL_CC_LIB_DEPS} - ${ABSL_CC_LIB_LINKOPTS} - ${ABSL_DEFAULT_LINKOPTS} + PUBLIC ${ABSL_CC_LIB_DEPS} + PRIVATE + ${ABSL_CC_LIB_LINKOPTS} + ${ABSL_DEFAULT_LINKOPTS} ) - target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES}) + else() + message(FATAL_ERROR "Invalid build type: ${_build_type}") endif() - # TODO currently we don't install googletest alongside abseil sources, so - # installed abseil can't be tested. - if(NOT ABSL_CC_LIB_TESTONLY AND ABSL_ENABLE_INSTALL) - install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets - RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR} - LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR} + # Linker language can be inferred from sources, but in the case of DLLs we + # don't have any .cc files so it would be ambiguous. We could set it + # explicitly only in the case of DLLs but, because "CXX" is always the + # correct linker language for static or for shared libraries, we set it + # unconditionally. + set_property(TARGET ${_NAME} PROPERTY LINKER_LANGUAGE "CXX") + + target_include_directories(${_NAME} + PUBLIC + "$" + $ + ) + target_compile_options(${_NAME} + PRIVATE ${ABSL_CC_LIB_COPTS}) + target_compile_definitions(${_NAME} PUBLIC ${ABSL_CC_LIB_DEFINES}) + + # Add all Abseil targets to a a folder in the IDE for organization. + if(ABSL_CC_LIB_PUBLIC) + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}) + elseif(ABSL_CC_LIB_TESTONLY) + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test) + else() + set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/internal) + endif() + + # INTERFACE libraries can't have the CXX_STANDARD property set + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) + set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) + + # When being installed, we lose the absl_ prefix. We want to put it back + # to have properly named lib files. This is a no-op when we are not being + # installed. + if(ABSL_ENABLE_INSTALL) + set_target_properties(${_NAME} PROPERTIES + OUTPUT_NAME "absl_${_NAME}" ) endif() + else() + # Generating header-only library + add_library(${_NAME} INTERFACE) + target_include_directories(${_NAME} + INTERFACE + "$" + $ + ) - add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME}) + if (${_build_type} STREQUAL "dll") + set(ABSL_CC_LIB_DEPS abseil_dll) + endif() + + target_link_libraries(${_NAME} + INTERFACE + ${ABSL_CC_LIB_DEPS} + ${ABSL_CC_LIB_LINKOPTS} + ${ABSL_DEFAULT_LINKOPTS} + ) + target_compile_definitions(${_NAME} INTERFACE ${ABSL_CC_LIB_DEFINES}) + endif() + + # TODO currently we don't install googletest alongside abseil sources, so + # installed abseil can't be tested. + if(NOT ABSL_CC_LIB_TESTONLY AND ABSL_ENABLE_INSTALL) + install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets + RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR} + LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR} + ) endif() + + add_library(absl::${ABSL_CC_LIB_NAME} ALIAS ${_NAME}) endfunction() # absl_cc_test() @@ -224,23 +296,42 @@ function(absl_cc_test) ) set(_NAME "absl_${ABSL_CC_TEST_NAME}") + add_executable(${_NAME} "") target_sources(${_NAME} PRIVATE ${ABSL_CC_TEST_SRCS}) target_include_directories(${_NAME} PUBLIC ${ABSL_COMMON_INCLUDE_DIRS} PRIVATE ${GMOCK_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS} ) - target_compile_definitions(${_NAME} - PUBLIC ${ABSL_CC_TEST_DEFINES} - ) + + if (${ABSL_BUILD_DLL}) + target_compile_definitions(${_NAME} + PUBLIC + ${ABSL_CC_TEST_DEFINES} + ABSL_CONSUME_DLL + GTEST_LINKED_AS_SHARED_LIBRARY=1 + ) + + # Replace dependencies on targets inside the DLL with abseil_dll itself. + absl_internal_dll_targets( + DEPS ${ABSL_CC_TEST_DEPS} + OUTPUT ABSL_CC_TEST_DEPS + ) + else() + target_compile_definitions(${_NAME} + PUBLIC + ${ABSL_CC_TEST_DEFINES} + ) + endif() target_compile_options(${_NAME} PRIVATE ${ABSL_CC_TEST_COPTS} ) + target_link_libraries(${_NAME} PUBLIC ${ABSL_CC_TEST_DEPS} PRIVATE ${ABSL_CC_TEST_LINKOPTS} ) - # Add all Abseil targets to a a folder in the IDE for organization. + # Add all Abseil targets to a folder in the IDE for organization. set_property(TARGET ${_NAME} PROPERTY FOLDER ${ABSL_IDE_FOLDER}/test) set_property(TARGET ${_NAME} PROPERTY CXX_STANDARD ${ABSL_CXX_STANDARD}) diff --git a/CMake/Googletest/DownloadGTest.cmake b/CMake/Googletest/DownloadGTest.cmake index 3c682aef..8a00b455 100644 --- a/CMake/Googletest/DownloadGTest.cmake +++ b/CMake/Googletest/DownloadGTest.cmake @@ -7,6 +7,13 @@ configure_file( ${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt ) +set(ABSL_SAVE_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +set(ABSL_SAVE_CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +if (BUILD_SHARED_LIBS) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGTEST_CREATE_SHARED_LIBRARY=1") +endif() + # Configure and build the downloaded googletest source execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . RESULT_VARIABLE result @@ -22,6 +29,9 @@ if(result) message(FATAL_ERROR "Build step for googletest failed: ${result}") endif() +set(CMAKE_CXX_FLAGS ${ABSL_SAVE_CMAKE_CXX_FLAGS}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ABSL_SAVE_CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + # Prevent overriding the parent project's compiler/linker settings on Windows set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86f56344..fdfb2cfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,12 @@ cmake_policy(SET CMP0048 NEW) project(absl CXX) +# Output directory is correct by default for most build setups. However, when +# building Abseil as a DLL, it is important to have the DLL in the same +# directory as the executable using it. Thus, we put all executables in a single +# /bin directory. +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + # when absl is included as subproject (i.e. using add_subdirectory(abseil-cpp)) # in the source tree of a project that uses it, install rules are disabled. if(NOT "^${CMAKE_SOURCE_DIR}$" STREQUAL "^${PROJECT_SOURCE_DIR}$") @@ -47,6 +53,7 @@ list(APPEND CMAKE_MODULE_PATH include(AbseilInstallDirs) include(CMakePackageConfigHelpers) +include(AbseilDll) include(AbseilHelpers) diff --git a/absl/CMakeLists.txt b/absl/CMakeLists.txt index 3e78397c..a1b1f8d8 100644 --- a/absl/CMakeLists.txt +++ b/absl/CMakeLists.txt @@ -14,8 +14,6 @@ # limitations under the License. # - - add_subdirectory(base) add_subdirectory(algorithm) add_subdirectory(container) @@ -31,3 +29,7 @@ add_subdirectory(synchronization) add_subdirectory(time) add_subdirectory(types) add_subdirectory(utility) + +if (${ABSL_BUILD_DLL}) + absl_make_dll() +endif() diff --git a/absl/base/attributes.h b/absl/base/attributes.h index acd1c526..8f77db77 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -563,7 +563,19 @@ // ABSL_ATTRIBUTE_PACKED // -// Prevents the compiler from padding a structure to natural alignment +// Instructs the compiler not to use natural alignment for a tagged data +// structure, but instead to reduce its alignment to 1. This attribute can +// either be applied to members of a structure or to a structure in its +// entirety. Applying this attribute (judiciously) to a structure in its +// entirety to optimize the memory footprint of very commonly-used structs is +// fine. Do not apply this attribute to a structure in its entirety if the +// purpose is to control the offsets of the members in the structure. Instead, +// apply this attribute only to structure members that need it. +// +// When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the +// natural alignment of structure members not annotated is preserved. Aligned +// member accesses are faster than non-aligned member accesses even if the +// targeted microprosessor supports non-aligned accesses. #if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__)) #define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) #else diff --git a/absl/base/config.h b/absl/base/config.h index c4e8dce4..eac5d268 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -643,4 +643,23 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #undef ABSL_INTERNAL_HAS_KEYWORD +// ABSL_DLL +// +// When building Abseil as a DLL, this macro expands to `__declspec(dllexport)` +// so we can annotate symbols appropriately as being exported. When used in +// headers consuming a DLL, this macro expands to `__declspec(dllimport)` so +// that consumers know the symbol is defined inside the DLL. In all other cases, +// the macro expands to nothing. +#if defined(_MSC_VER) +#if defined(ABSL_BUILD_DLL) +#define ABSL_DLL __declspec(dllexport) +#elif defined(ABSL_CONSUME_DLL) +#define ABSL_DLL __declspec(dllimport) +#else +#define ABSL_DLL +#endif +#else +#define ABSL_DLL +#endif // defined(_MSC_VER) + #endif // ABSL_BASE_CONFIG_H_ diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc index d79c5486..e36eb29a 100644 --- a/absl/base/internal/raw_logging.cc +++ b/absl/base/internal/raw_logging.cc @@ -225,8 +225,9 @@ bool RawLoggingFullySupported() { #endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED } -ABSL_CONST_INIT absl::base_internal::AtomicHook - internal_log_function(DefaultInternalLog); +ABSL_CONST_INIT ABSL_DLL + absl::base_internal::AtomicHook + internal_log_function(DefaultInternalLog); void RegisterInternalLogFunction(InternalLogFunction func) { internal_log_function.Store(func); diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h index cff45058..ac74f97d 100644 --- a/absl/base/internal/raw_logging.h +++ b/absl/base/internal/raw_logging.h @@ -22,9 +22,11 @@ #include #include "absl/base/attributes.h" +#include "absl/base/config.h" #include "absl/base/internal/atomic_hook.h" #include "absl/base/log_severity.h" #include "absl/base/macros.h" +#include "absl/base/optimization.h" #include "absl/base/port.h" // This is similar to LOG(severity) << format..., but @@ -168,7 +170,8 @@ using InternalLogFunction = void (*)(absl::LogSeverity severity, const char* file, int line, const std::string& message); -extern base_internal::AtomicHook internal_log_function; +ABSL_DLL extern base_internal::AtomicHook + internal_log_function; void RegisterInternalLogFunction(InternalLogFunction func); diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc index 7945322f..a0930e97 100644 --- a/absl/base/internal/sysinfo.cc +++ b/absl/base/internal/sysinfo.cc @@ -58,10 +58,6 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace base_internal { -static once_flag init_system_info_once; -static int num_cpus = 0; -static double nominal_cpu_frequency = 1.0; // 0.0 might be dangerous. - static int GetNumCPUs() { #if defined(__myriad2__) return 1; @@ -265,21 +261,27 @@ static double GetNominalCPUFrequency() { #endif -// InitializeSystemInfo() may be called before main() and before -// malloc is properly initialized, therefore this must not allocate -// memory. -static void InitializeSystemInfo() { - num_cpus = GetNumCPUs(); - nominal_cpu_frequency = GetNominalCPUFrequency(); -} +ABSL_CONST_INIT static once_flag init_num_cpus_once; +ABSL_CONST_INIT static int num_cpus = 0; +// NumCPUs() may be called before main() and before malloc is properly +// initialized, therefore this must not allocate memory. int NumCPUs() { - base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo); + base_internal::LowLevelCallOnce( + &init_num_cpus_once, []() { num_cpus = GetNumCPUs(); }); return num_cpus; } +// A default frequency of 0.0 might be dangerous if it is used in division. +ABSL_CONST_INIT static once_flag init_nominal_cpu_frequency_once; +ABSL_CONST_INIT static double nominal_cpu_frequency = 1.0; + +// NominalCPUFrequency() may be called before main() and before malloc is +// properly initialized, therefore this must not allocate memory. double NominalCPUFrequency() { - base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo); + base_internal::LowLevelCallOnce( + &init_nominal_cpu_frequency_once, + []() { nominal_cpu_frequency = GetNominalCPUFrequency(); }); return nominal_cpu_frequency; } diff --git a/absl/base/internal/thread_identity.cc b/absl/base/internal/thread_identity.cc index 6a28f246..d63a04ae 100644 --- a/absl/base/internal/thread_identity.cc +++ b/absl/base/internal/thread_identity.cc @@ -113,6 +113,18 @@ void SetCurrentThreadIdentity( #endif } +#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ + ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 + +// Please see the comment on `CurrentThreadIdentityIfPresent` in +// thread_identity.h. Because DLLs cannot expose thread_local variables in +// headers, we opt for the correct-but-slower option of placing the definition +// of this function only in a translation unit inside DLL. +#if defined(ABSL_BUILD_DLL) || defined(ABSL_CONSUME_DLL) +ThreadIdentity* CurrentThreadIdentityIfPresent() { return thread_identity_ptr; } +#endif +#endif + void ClearCurrentThreadIdentity() { #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 diff --git a/absl/base/internal/thread_identity.h b/absl/base/internal/thread_identity.h index 5dfd0715..ceb109b4 100644 --- a/absl/base/internal/thread_identity.h +++ b/absl/base/internal/thread_identity.h @@ -30,6 +30,7 @@ #include #include +#include "absl/base/config.h" #include "absl/base/internal/per_thread_tls.h" namespace absl { @@ -234,9 +235,17 @@ ABSL_CONST_INIT extern thread_local ThreadIdentity* thread_identity_ptr; #error Thread-local storage not detected on this platform #endif +// thread_local variables cannot be in headers exposed by DLLs. However, it is +// important for performance reasons in general that +// `CurrentThreadIdentityIfPresent` be inlined. This is not possible across a +// DLL boundary so, with DLLs, we opt to have the function not be inlined. Note +// that `CurrentThreadIdentityIfPresent` is declared above so we can exclude +// this entire inline definition when compiling as a DLL. +#if !defined(ABSL_BUILD_DLL) && !defined(ABSL_CONSUME_DLL) inline ThreadIdentity* CurrentThreadIdentityIfPresent() { return thread_identity_ptr; } +#endif #elif ABSL_THREAD_IDENTITY_MODE != \ ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC diff --git a/absl/base/options.h b/absl/base/options.h index 592b33b7..6868c77b 100644 --- a/absl/base/options.h +++ b/absl/base/options.h @@ -66,7 +66,13 @@ // NOTE: the defaults within this file all assume that Abseil can select the // proper Abseil implementation at compile-time, which will not be sufficient // to guarantee ABI stability to package managers. -// + +// Include a standard library header to allow configuration based on the +// standard library in use. +#ifdef __cplusplus +#include +#endif + // ----------------------------------------------------------------------------- // Type Compatibility Options // ----------------------------------------------------------------------------- @@ -158,7 +164,6 @@ #define ABSL_OPTION_USE_STD_STRING_VIEW 2 - // ABSL_OPTION_USE_STD_VARIANT // // This option controls whether absl::variant is implemented as an alias to diff --git a/absl/container/btree_map.h b/absl/container/btree_map.h index cbfcb58c..d23f4ee5 100644 --- a/absl/container/btree_map.h +++ b/absl/container/btree_map.h @@ -226,6 +226,30 @@ class btree_map // Inserts the elements within the initializer list `ilist`. using Base::insert; + // btree_map::insert_or_assign() + // + // Inserts an element of the specified value into the `btree_map` provided + // that a value with the given key does not already exist, or replaces the + // corresponding mapped type with the forwarded `obj` argument if a key for + // that value already exists, returning an iterator pointing to the newly + // inserted element. Overloads are listed below. + // + // pair insert_or_assign(const key_type& k, M&& obj): + // pair insert_or_assign(key_type&& k, M&& obj): + // + // Inserts/Assigns (or moves) the element of the specified key into the + // `btree_map`. If the returned bool is true, insertion took place, and if + // it's false, assignment took place. + // + // iterator insert_or_assign(const_iterator hint, + // const key_type& k, M&& obj): + // iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj): + // + // Inserts/Assigns (or moves) the element of the specified key into the + // `btree_map` using the position of `hint` as a non-binding suggestion + // for where to begin the insertion search. + using Base::insert_or_assign; + // btree_map::emplace() // // Inserts an element of the specified value by constructing it in-place diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc index 8692b9c2..af8ee00b 100644 --- a/absl/container/btree_test.cc +++ b/absl/container/btree_test.cc @@ -2345,6 +2345,65 @@ TEST(Btree, EraseIf) { } } +TEST(Btree, InsertOrAssign) { + absl::btree_map m = {{1, 1}, {3, 3}}; + using value_type = typename decltype(m)::value_type; + + auto ret = m.insert_or_assign(4, 4); + EXPECT_EQ(*ret.first, value_type(4, 4)); + EXPECT_TRUE(ret.second); + ret = m.insert_or_assign(3, 100); + EXPECT_EQ(*ret.first, value_type(3, 100)); + EXPECT_FALSE(ret.second); + + auto hint_ret = m.insert_or_assign(ret.first, 3, 200); + EXPECT_EQ(*hint_ret, value_type(3, 200)); + hint_ret = m.insert_or_assign(m.find(1), 0, 1); + EXPECT_EQ(*hint_ret, value_type(0, 1)); + // Test with bad hint. + hint_ret = m.insert_or_assign(m.end(), -1, 1); + EXPECT_EQ(*hint_ret, value_type(-1, 1)); + + EXPECT_THAT(m, ElementsAre(Pair(-1, 1), Pair(0, 1), Pair(1, 1), Pair(3, 200), + Pair(4, 4))); +} + +TEST(Btree, InsertOrAssignMovableOnly) { + absl::btree_map m; + using value_type = typename decltype(m)::value_type; + + auto ret = m.insert_or_assign(4, MovableOnlyInstance(4)); + EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(4))); + EXPECT_TRUE(ret.second); + ret = m.insert_or_assign(4, MovableOnlyInstance(100)); + EXPECT_EQ(*ret.first, value_type(4, MovableOnlyInstance(100))); + EXPECT_FALSE(ret.second); + + auto hint_ret = m.insert_or_assign(ret.first, 3, MovableOnlyInstance(200)); + EXPECT_EQ(*hint_ret, value_type(3, MovableOnlyInstance(200))); + + EXPECT_EQ(m.size(), 2); +} + +TEST(Btree, BitfieldArgument) { + union { + int n : 1; + }; + n = 0; + absl::btree_map m; + m.erase(n); + m.count(n); + m.find(n); + m.contains(n); + m.equal_range(n); + m.insert_or_assign(n, n); + m.insert_or_assign(m.end(), n, n); + m.try_emplace(n); + m.try_emplace(m.end(), n); + m.at(n); + m[n]; +} + } // namespace } // namespace container_internal ABSL_NAMESPACE_END diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h index 04795c2e..3e6ff4b8 100644 --- a/absl/container/internal/btree_container.h +++ b/absl/container/internal/btree_container.h @@ -372,7 +372,7 @@ class btree_map_container : public btree_set_container { using super_type = btree_set_container; using params_type = typename Tree::params_type; - protected: + private: template using key_arg = typename super_type::template key_arg; @@ -390,6 +390,69 @@ class btree_map_container : public btree_set_container { btree_map_container() {} // Insertion routines. + // Note: the nullptr template arguments and extra `const M&` overloads allow + // for supporting bitfield arguments. + // Note: when we call `std::forward(obj)` twice, it's safe because + // insert_unique/insert_hint_unique are guaranteed to not consume `obj` when + // `ret.second` is false. + template + std::pair insert_or_assign(const key_type &k, const M &obj) { + const std::pair ret = this->tree_.insert_unique(k, k, obj); + if (!ret.second) ret.first->second = obj; + return ret; + } + template + std::pair insert_or_assign(key_type &&k, const M &obj) { + const std::pair ret = + this->tree_.insert_unique(k, std::move(k), obj); + if (!ret.second) ret.first->second = obj; + return ret; + } + template + std::pair insert_or_assign(const key_type &k, M &&obj) { + const std::pair ret = + this->tree_.insert_unique(k, k, std::forward(obj)); + if (!ret.second) ret.first->second = std::forward(obj); + return ret; + } + template + std::pair insert_or_assign(key_type &&k, M &&obj) { + const std::pair ret = + this->tree_.insert_unique(k, std::move(k), std::forward(obj)); + if (!ret.second) ret.first->second = std::forward(obj); + return ret; + } + template + iterator insert_or_assign(const_iterator position, const key_type &k, + const M &obj) { + const std::pair ret = + this->tree_.insert_hint_unique(iterator(position), k, k, obj); + if (!ret.second) ret.first->second = obj; + return ret.first; + } + template + iterator insert_or_assign(const_iterator position, key_type &&k, + const M &obj) { + const std::pair ret = this->tree_.insert_hint_unique( + iterator(position), k, std::move(k), obj); + if (!ret.second) ret.first->second = obj; + return ret.first; + } + template + iterator insert_or_assign(const_iterator position, const key_type &k, + M &&obj) { + const std::pair ret = this->tree_.insert_hint_unique( + iterator(position), k, k, std::forward(obj)); + if (!ret.second) ret.first->second = std::forward(obj); + return ret.first; + } + template + iterator insert_or_assign(const_iterator position, key_type &&k, M &&obj) { + const std::pair ret = this->tree_.insert_hint_unique( + iterator(position), k, std::move(k), std::forward(obj)); + if (!ret.second) ret.first->second = std::forward(obj); + return ret.first; + } template std::pair try_emplace(const key_type &k, Args &&... args) { return this->tree_.insert_unique( diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index e15f4444..56447251 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -39,17 +39,16 @@ ABSL_CONST_INIT std::atomic g_hashtablez_enabled{ ABSL_CONST_INIT std::atomic g_hashtablez_sample_parameter{1 << 10}; ABSL_CONST_INIT std::atomic g_hashtablez_max_samples{1 << 20}; -#if ABSL_PER_THREAD_TLS == 1 +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) ABSL_PER_THREAD_TLS_KEYWORD absl::base_internal::ExponentialBiased g_exponential_biased_generator; #endif } // namespace -#if ABSL_PER_THREAD_TLS == 1 +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0; -#endif // ABSL_PER_THREAD_TLS == 1 - +#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) HashtablezSampler& HashtablezSampler::Global() { static auto* sampler = new HashtablezSampler(); @@ -192,7 +191,7 @@ HashtablezInfo* SampleSlow(int64_t* next_sample) { return HashtablezSampler::Global().Register(); } -#if ABSL_PER_THREAD_TLS == 0 +#if !defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) *next_sample = std::numeric_limits::max(); return nullptr; #else diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index c4f9629f..34d5e572 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -180,14 +180,23 @@ class HashtablezInfoHandle { HashtablezInfo* info_; }; -#if ABSL_PER_THREAD_TLS == 1 +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) +#error ABSL_INTERNAL_HASHTABLEZ_SAMPLE cannot be directly set +#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) + +#if (ABSL_PER_THREAD_TLS == 1) && !defined(ABSL_BUILD_DLL) && \ + !defined(ABSL_CONSUME_DLL) +#define ABSL_INTERNAL_HASHTABLEZ_SAMPLE +#endif + +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) extern ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample; #endif // ABSL_PER_THREAD_TLS // Returns an RAII sampling handle that manages registration and unregistation // with the global sampler. inline HashtablezInfoHandle Sample() { -#if ABSL_PER_THREAD_TLS == 1 +#if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) if (ABSL_PREDICT_TRUE(--global_next_sample > 0)) { return HashtablezInfoHandle(nullptr); } diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index 102b2375..36f5ccdd 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc @@ -169,7 +169,7 @@ TEST(HashtablezInfoTest, RecordRehash) { EXPECT_EQ(info.num_erases.load(), 0); } -#if ABSL_PER_THREAD_TLS == 1 +#if defined(ABSL_HASHTABLEZ_SAMPLE) TEST(HashtablezSamplerTest, SmallSampleParameter) { SetHashtablezEnabled(true); SetHashtablezSampleParameter(100); diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index 38e5e0e8..a96ae68a 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -418,53 +418,6 @@ TEST(Table, Empty) { EXPECT_TRUE(t.empty()); } -#ifdef __GNUC__ -template -ABSL_ATTRIBUTE_ALWAYS_INLINE inline void DoNotOptimize(const T& v) { - asm volatile("" : : "r,m"(v) : "memory"); -} -#endif - -TEST(Table, Prefetch) { - IntTable t; - t.emplace(1); - // Works for both present and absent keys. - t.prefetch(1); - t.prefetch(2); - - // Do not run in debug mode, when prefetch is not implemented, or when - // sanitizers are enabled, or on WebAssembly. -#if defined(NDEBUG) && defined(__GNUC__) && defined(__x86_64__) && \ - !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) && \ - !defined(THREAD_SANITIZER) && !defined(UNDEFINED_BEHAVIOR_SANITIZER) && \ - !defined(__EMSCRIPTEN__) - const auto now = [] { return absl::base_internal::CycleClock::Now(); }; - - // Make size enough to not fit in L2 cache (16.7 Mb) - static constexpr int size = 1 << 22; - for (int i = 0; i < size; ++i) t.insert(i); - - int64_t no_prefetch = 0, prefetch = 0; - for (int iter = 0; iter < 10; ++iter) { - int64_t time = now(); - for (int i = 0; i < size; ++i) { - DoNotOptimize(t.find(i)); - } - no_prefetch += now() - time; - - time = now(); - for (int i = 0; i < size; ++i) { - t.prefetch(i + 20); - DoNotOptimize(t.find(i)); - } - prefetch += now() - time; - } - - // no_prefetch is at least 30% slower. - EXPECT_GE(1.0 * no_prefetch / prefetch, 1.3); -#endif -} - TEST(Table, LookupEmpty) { IntTable t; auto it = t.find(0); @@ -1842,7 +1795,7 @@ TEST(TableDeathTest, EraseOfEndAsserts) { EXPECT_DEATH_IF_SUPPORTED(t.erase(t.end()), kDeathMsg); } -#if ABSL_PER_THREAD_TLS == 1 +#if defined(ABSL_HASHTABLEZ_SAMPLE) TEST(RawHashSamplerTest, Sample) { // Enable the feature even if the prod default is off. SetHashtablezEnabled(true); @@ -1863,7 +1816,7 @@ TEST(RawHashSamplerTest, Sample) { EXPECT_NEAR((end_size - start_size) / static_cast(tables.size()), 0.01, 0.005); } -#endif +#endif // ABSL_HASHTABLEZ_SAMPLER TEST(RawHashSamplerTest, DoNotSampleCustomAllocators) { // Enable the feature even if the prod default is off. diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake index 7543928a..77d4ace8 100644 --- a/absl/copts/AbseilConfigureCopts.cmake +++ b/absl/copts/AbseilConfigureCopts.cmake @@ -5,6 +5,13 @@ set(ABSL_LSAN_LINKOPTS "") set(ABSL_HAVE_LSAN OFF) set(ABSL_DEFAULT_LINKOPTS "") +if (BUILD_SHARED_LIBS AND MSVC) + set(ABSL_BUILD_DLL TRUE) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) +else() + set(ABSL_BUILD_DLL FALSE) +endif() + if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64") if (MSVC) set(ABSL_RANDOM_RANDEN_COPTS "${ABSL_RANDOM_HWAES_MSVC_X64_FLAGS}") diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc index 0bac60b9..a1d03aab 100644 --- a/absl/debugging/symbolize_test.cc +++ b/absl/debugging/symbolize_test.cc @@ -473,6 +473,7 @@ void ABSL_ATTRIBUTE_NOINLINE TestWithReturnAddress() { } #elif defined(_WIN32) +#if !defined(ABSL_CONSUME_DLL) TEST(Symbolize, Basics) { EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func))); @@ -511,6 +512,7 @@ TEST(Symbolize, SymbolizeWithDemangling) { EXPECT_TRUE(strstr(result, "Foo::func") != nullptr) << result; } +#endif // !defined(ABSL_CONSUME_DLL) #else // Symbolizer unimplemented TEST(Symbolize, Unimplemented) { diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 6c7b2b6e..cbdbae52 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -324,6 +324,23 @@ cc_test( ], ) +cc_binary( + name = "flag_benchmark", + testonly = 1, + srcs = [ + "flag_benchmark.cc", + ], + copts = ABSL_TEST_COPTS, + tags = ["benchmark"], + visibility = ["//visibility:private"], + deps = [ + ":flag", + "//absl/time", + "//absl/types:optional", + "@com_github_google_benchmark//:benchmark_main", + ], +) + cc_test( name = "marshalling_test", size = "small", diff --git a/absl/flags/flag.cc b/absl/flags/flag.cc index 9af80079..e67f7304 100644 --- a/absl/flags/flag.cc +++ b/absl/flags/flag.cc @@ -22,7 +22,14 @@ namespace absl { ABSL_NAMESPACE_BEGIN -// This global nutex protects on-demand construction of flag objects in MSVC +#ifndef NDEBUG +#define ABSL_FLAGS_GET(T) \ + T GetFlag(const absl::Flag& flag) { return flag.Get(); } +ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_GET) +#undef ABSL_FLAGS_GET +#endif + +// This global mutex protects on-demand construction of flag objects in MSVC // builds. #if defined(_MSC_VER) && !defined(__clang__) diff --git a/absl/flags/flag.h b/absl/flags/flag.h index cc22cdb9..bd61668f 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -186,25 +186,29 @@ class Flag { // // // FLAGS_firstname is a Flag of type `std::string` // std::string first_name = absl::GetFlag(FLAGS_firstname); -template ::value, int>::type = 0> -ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag) { - return flag.Get(); -} - +#ifndef NDEBUG // We want to validate the type mismatch between type definition and // declaration. The lock-free implementation does not allow us to do it, // so in debug builds we always use the slower implementation, which always // validates the type. -#ifndef NDEBUG +template +ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag) { + return flag.Get(); +} +// We currently need an external linkage for built-in types because shared +// libraries have different addresses of flags_internal::FlagOps which +// might cause log spam when checking the same flag type. +#define ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT(T) \ + ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag); +ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT) +#undef ABSL_FLAGS_INTERNAL_BUILT_IN_EXPORT +#else template ::value, int>::type = 0> + !flags_internal::IsAtomicFlagTypeTrait::value, int>::type = 0> ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag) { return flag.Get(); } -#else // Overload for `GetFlag()` for types that support lock-free reads. template ; +using AbslDuration = absl::Duration; + +// We do not want to take over marshalling for the types absl::optional, +// absl::optional which we do not own. Instead we introduce unique +// "aliases" to these types, which we do. +using AbslOptionalInt = absl::optional; +struct OptionalInt : AbslOptionalInt { + using AbslOptionalInt::AbslOptionalInt; +}; +// Next two functions represent Abseil Flags marshalling for OptionalInt. +bool AbslParseFlag(absl::string_view src, OptionalInt* flag, + std::string* error) { + int val; + if (src.empty()) + flag->reset(); + else if (!absl::ParseFlag(src, &val, error)) + return false; + *flag = val; + return true; +} +std::string AbslUnparseFlag(const OptionalInt& flag) { + return !flag ? "" : absl::UnparseFlag(*flag); +} + +using AbslOptionalString = absl::optional; +struct OptionalString : AbslOptionalString { + using AbslOptionalString::AbslOptionalString; +}; +// Next two functions represent Abseil Flags marshalling for OptionalString. +bool AbslParseFlag(absl::string_view src, OptionalString* flag, + std::string* error) { + std::string val; + if (src.empty()) + flag->reset(); + else if (!absl::ParseFlag(src, &val, error)) + return false; + *flag = val; + return true; +} +std::string AbslUnparseFlag(const OptionalString& flag) { + return !flag ? "" : absl::UnparseFlag(*flag); +} + +struct UDT { + UDT() = default; + UDT(const UDT&) {} + UDT& operator=(const UDT&) { return *this; } +}; +// Next two functions represent Abseil Flags marshalling for UDT. +bool AbslParseFlag(absl::string_view, UDT*, std::string*) { return true; } +std::string AbslUnparseFlag(const UDT&) { return ""; } + +} // namespace + +#define BENCHMARKED_TYPES(A) \ + A(bool) \ + A(int16_t) \ + A(uint16_t) \ + A(int32_t) \ + A(uint32_t) \ + A(int64_t) \ + A(uint64_t) \ + A(double) \ + A(float) \ + A(String) \ + A(VectorOfStrings) \ + A(OptionalInt) \ + A(OptionalString) \ + A(AbslDuration) \ + A(UDT) + +#define FLAG_DEF(T) ABSL_FLAG(T, T##_flag, {}, ""); + +BENCHMARKED_TYPES(FLAG_DEF) + +namespace { + +#define BM_GetFlag(T) \ + void BM_GetFlag_##T(benchmark::State& state) { \ + for (auto _ : state) { \ + benchmark::DoNotOptimize(absl::GetFlag(FLAGS_##T##_flag)); \ + } \ + } \ + BENCHMARK(BM_GetFlag_##T); + +BENCHMARKED_TYPES(BM_GetFlag) + +} // namespace diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 8639181f..ae7a60cd 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -708,7 +708,8 @@ struct is_hashable : std::integral_constant::value> {}; // CityHashState -class CityHashState : public HashStateBase { +class ABSL_DLL CityHashState + : public HashStateBase { // absl::uint128 is not an alias or a thin wrapper around the intrinsic. // We use the intrinsic when available to improve performance. #ifdef ABSL_HAVE_INTRINSIC_INT128 diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc index a20a77e7..b605a870 100644 --- a/absl/numeric/int128.cc +++ b/absl/numeric/int128.cc @@ -25,8 +25,8 @@ namespace absl { ABSL_NAMESPACE_BEGIN -const uint128 kuint128max = MakeUint128(std::numeric_limits::max(), - std::numeric_limits::max()); +ABSL_DLL const uint128 kuint128max = MakeUint128( + std::numeric_limits::max(), std::numeric_limits::max()); namespace { diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 718f70b1..636e3a5b 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h @@ -234,7 +234,7 @@ class // Prefer to use the constexpr `Uint128Max()`. // // TODO(absl-team) deprecate kuint128max once migration tool is released. -extern const uint128 kuint128max; +ABSL_DLL extern const uint128 kuint128max; // allow uint128 to be logged std::ostream& operator<<(std::ostream& os, uint128 v); diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index 2585b397..f78fbc7e 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -67,6 +67,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ "//absl/base:base_internal", + "//absl/base:config", "//absl/base:core_headers", "//absl/meta:type_traits", "//absl/random/internal:distributions", @@ -183,6 +184,7 @@ cc_test( timeout = "eternal", # Android can take a very long time srcs = ["beta_distribution_test.cc"], copts = ABSL_TEST_COPTS, + flaky = 1, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":distributions", diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index 46dbc3ef..efa55d8f 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -183,6 +183,7 @@ absl_cc_library( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::base_internal + absl::config absl::core_headers absl::random_internal_generate_real absl::random_internal_distributions diff --git a/absl/random/gaussian_distribution.h b/absl/random/gaussian_distribution.h index c1427b06..4b07a5c0 100644 --- a/absl/random/gaussian_distribution.h +++ b/absl/random/gaussian_distribution.h @@ -28,6 +28,7 @@ #include #include +#include "absl/base/config.h" #include "absl/random/internal/fast_uniform_bits.h" #include "absl/random/internal/generate_real.h" #include "absl/random/internal/iostream_state_saver.h" @@ -43,7 +44,7 @@ namespace random_internal { // The specific algorithm has some of the improvements suggested by the // 2005 paper, "An Improved Ziggurat Method to Generate Normal Random Samples", // Jurgen A Doornik. (https://www.doornik.com/research/ziggurat.pdf) -class gaussian_distribution_base { +class ABSL_DLL gaussian_distribution_base { public: template inline double zignor(URBG& g); // NOLINT(runtime/references) diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index dc7e1bfd..d5a362d0 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -37,7 +37,6 @@ cc_library( "internal/charconv_bigint.h", "internal/charconv_parse.cc", "internal/charconv_parse.h", - "internal/escaping.cc", "internal/memutil.cc", "internal/memutil.h", "internal/stl_type_traits.h", @@ -55,7 +54,6 @@ cc_library( "ascii.h", "charconv.h", "escaping.h", - "internal/escaping.h", "match.h", "numbers.h", "str_cat.h", @@ -85,11 +83,13 @@ cc_library( cc_library( name = "internal", srcs = [ + "internal/escaping.cc", "internal/ostringstream.cc", "internal/utf8.cc", ], hdrs = [ "internal/char_map.h", + "internal/escaping.h", "internal/ostringstream.h", "internal/resize_uninitialized.h", "internal/utf8.h", @@ -99,6 +99,7 @@ cc_library( "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", + "//absl/base:raw_logging_internal", "//absl/meta:type_traits", ], ) diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index 36702f71..3feb5e94 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -38,8 +38,6 @@ absl_cc_library( "internal/charconv_bigint.h" "internal/charconv_parse.cc" "internal/charconv_parse.h" - "internal/escaping.cc" - "internal/escaping.h" "internal/memutil.cc" "internal/memutil.h" "internal/stl_type_traits.h" @@ -74,6 +72,8 @@ absl_cc_library( strings_internal HDRS "internal/char_map.h" + "internal/escaping.cc" + "internal/escaping.h" "internal/ostringstream.h" "internal/resize_uninitialized.h" "internal/utf8.h" @@ -86,6 +86,7 @@ absl_cc_library( absl::config absl::core_headers absl::endian + absl::raw_logging_internal absl::type_traits ) diff --git a/absl/strings/ascii.cc b/absl/strings/ascii.cc index abea3e4f..93bb03e9 100644 --- a/absl/strings/ascii.cc +++ b/absl/strings/ascii.cc @@ -57,7 +57,7 @@ namespace ascii_internal { // of these bits is tightly coupled to this implementation, the individual bits // are not named. Note that bitfields for all characters above ASCII 127 are // zero-initialized. -const unsigned char kPropertyBits[256] = { +ABSL_DLL const unsigned char kPropertyBits[256] = { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x00 0x40, 0x68, 0x48, 0x48, 0x48, 0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x10 @@ -79,7 +79,7 @@ const unsigned char kPropertyBits[256] = { // Array of characters for the ascii_tolower() function. For values 'A' // through 'Z', return the lower-case character; otherwise, return the // identity of the passed character. -const char kToLower[256] = { +ABSL_DLL const char kToLower[256] = { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', @@ -117,7 +117,7 @@ const char kToLower[256] = { // Array of characters for the ascii_toupper() function. For values 'a' // through 'z', return the upper-case character; otherwise, return the // identity of the passed character. -const char kToUpper[256] = { +ABSL_DLL const char kToUpper[256] = { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', diff --git a/absl/strings/ascii.h b/absl/strings/ascii.h index 792aabe5..b46bc71f 100644 --- a/absl/strings/ascii.h +++ b/absl/strings/ascii.h @@ -56,6 +56,7 @@ #include #include "absl/base/attributes.h" +#include "absl/base/config.h" #include "absl/strings/string_view.h" namespace absl { @@ -63,13 +64,13 @@ ABSL_NAMESPACE_BEGIN namespace ascii_internal { // Declaration for an array of bitfields holding character information. -extern const unsigned char kPropertyBits[256]; +ABSL_DLL extern const unsigned char kPropertyBits[256]; // Declaration for the array of characters to upper-case characters. -extern const char kToUpper[256]; +ABSL_DLL extern const char kToUpper[256]; // Declaration for the array of characters to lower-case characters. -extern const char kToLower[256]; +ABSL_DLL extern const char kToLower[256]; } // namespace ascii_internal diff --git a/absl/strings/internal/charconv_bigint.cc b/absl/strings/internal/charconv_bigint.cc index 860c27b2..66f33e72 100644 --- a/absl/strings/internal/charconv_bigint.cc +++ b/absl/strings/internal/charconv_bigint.cc @@ -158,12 +158,12 @@ const uint32_t* LargePowerOfFiveData(int i) { int LargePowerOfFiveSize(int i) { return 2 * i; } } // namespace -const uint32_t kFiveToNth[14] = { +ABSL_DLL const uint32_t kFiveToNth[14] = { 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125, }; -const uint32_t kTenToNth[10] = { +ABSL_DLL const uint32_t kTenToNth[10] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, }; diff --git a/absl/strings/internal/charconv_bigint.h b/absl/strings/internal/charconv_bigint.h index 108e1eb2..999e9ae3 100644 --- a/absl/strings/internal/charconv_bigint.h +++ b/absl/strings/internal/charconv_bigint.h @@ -20,6 +20,7 @@ #include #include +#include "absl/base/config.h" #include "absl/strings/ascii.h" #include "absl/strings/internal/charconv_parse.h" #include "absl/strings/string_view.h" @@ -33,8 +34,9 @@ constexpr int kMaxSmallPowerOfFive = 13; // The largest power that 10 that can be raised to, and still fit in a uint32_t. constexpr int kMaxSmallPowerOfTen = 9; -extern const uint32_t kFiveToNth[kMaxSmallPowerOfFive + 1]; -extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1]; +ABSL_DLL extern const uint32_t + kFiveToNth[kMaxSmallPowerOfFive + 1]; +ABSL_DLL extern const uint32_t kTenToNth[kMaxSmallPowerOfTen + 1]; // Large, fixed-width unsigned integer. // diff --git a/absl/strings/internal/str_format/bind.h b/absl/strings/internal/str_format/bind.h index 2bf0c085..cf41b197 100644 --- a/absl/strings/internal/str_format/bind.h +++ b/absl/strings/internal/str_format/bind.h @@ -122,8 +122,8 @@ class FormatSpecTemplate #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER template (), + AllOf(sizeof...(C) == sizeof...(Args), + Contains(ArgumentToConv(), C)...)>::type> FormatSpecTemplate(const ExtendedParsedFormat& pc) // NOLINT : Base(&pc) {} diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index 51d7dd6f..0a764035 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h @@ -17,10 +17,12 @@ #define ABSL_STRINGS_INTERNAL_STR_FORMAT_EXTENSION_H_ #include + #include #include #include +#include "absl/base/config.h" #include "absl/base/port.h" #include "absl/strings/internal/str_format/output.h" #include "absl/strings/string_view.h" @@ -134,7 +136,7 @@ struct Flags { } }; -struct LengthMod { +struct ABSL_DLL LengthMod { public: enum Id : uint8_t { h, hh, l, ll, L, j, z, t, q, none @@ -196,7 +198,7 @@ struct LengthMod { X_VAL(n) X_SEP X_VAL(p) // clang-format on -struct ConversionChar { +struct ABSL_DLL ConversionChar { public: enum Id : uint8_t { c, C, s, S, // text diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index a0e5a7fd..68c26dd6 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc @@ -900,9 +900,10 @@ inline bool safe_uint_internal(absl::string_view text, IntType* value_p, namespace numbers_internal { // Digit conversion. -ABSL_CONST_INIT const char kHexChar[] = "0123456789abcdef"; +ABSL_CONST_INIT ABSL_DLL const char kHexChar[] = + "0123456789abcdef"; -ABSL_CONST_INIT const char kHexTable[513] = +ABSL_CONST_INIT ABSL_DLL const char kHexTable[513] = "000102030405060708090a0b0c0d0e0f" "101112131415161718191a1b1c1d1e1f" "202122232425262728292a2b2c2d2e2f" @@ -920,7 +921,7 @@ ABSL_CONST_INIT const char kHexTable[513] = "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; -ABSL_CONST_INIT const char two_ASCII_digits[100][2] = { +ABSL_CONST_INIT ABSL_DLL const char two_ASCII_digits[100][2] = { {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'}, {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'}, {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'}, diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h index 61204683..d872cca5 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -36,6 +36,7 @@ #include #include +#include "absl/base/config.h" #include "absl/base/internal/bits.h" #ifdef __SSE4_2__ // TODO(jorg): Remove this when we figure out the right way @@ -106,9 +107,11 @@ ABSL_NAMESPACE_BEGIN namespace numbers_internal { // Digit conversion. -extern const char kHexChar[17]; // 0123456789abcdef -extern const char kHexTable[513]; // 000102030405060708090a0b0c0d0e0f1011... -extern const char two_ASCII_digits[100][2]; // 00, 01, 02, 03... +ABSL_DLL extern const char kHexChar[17]; // 0123456789abcdef +ABSL_DLL extern const char + kHexTable[513]; // 000102030405060708090a0b0c0d0e0f1011... +ABSL_DLL extern const char + two_ASCII_digits[100][2]; // 00, 01, 02, 03... // Writes a two-character representation of 'i' to 'buf'. 'i' must be in the // range 0 <= i < 100, and buf must have space for two characters. Example: diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 4f7dd6b3..01965b0e 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -28,7 +28,19 @@ #define ABSL_STRINGS_STRING_VIEW_H_ #include +#include +#include +#include +#include +#include +#include +#include + #include "absl/base/config.h" +#include "absl/base/internal/throw_delegate.h" +#include "absl/base/macros.h" +#include "absl/base/optimization.h" +#include "absl/base/port.h" #ifdef ABSL_USES_STD_STRING_VIEW @@ -49,19 +61,6 @@ ABSL_NAMESPACE_END #define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp #endif // ABSL_HAVE_BUILTIN(__builtin_memcmp) -#include -#include -#include -#include -#include -#include -#include - -#include "absl/base/internal/throw_delegate.h" -#include "absl/base/macros.h" -#include "absl/base/optimization.h" -#include "absl/base/port.h" - namespace absl { ABSL_NAMESPACE_BEGIN diff --git a/absl/time/format.cc b/absl/time/format.cc index 5997ef0c..ee088f33 100644 --- a/absl/time/format.cc +++ b/absl/time/format.cc @@ -24,11 +24,14 @@ namespace cctz = absl::time_internal::cctz; namespace absl { ABSL_NAMESPACE_BEGIN -extern const char RFC3339_full[] = "%Y-%m-%dT%H:%M:%E*S%Ez"; -extern const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez"; - -extern const char RFC1123_full[] = "%a, %d %b %E4Y %H:%M:%S %z"; -extern const char RFC1123_no_wday[] = "%d %b %E4Y %H:%M:%S %z"; +ABSL_DLL extern const char RFC3339_full[] = + "%Y-%m-%dT%H:%M:%E*S%Ez"; +ABSL_DLL extern const char RFC3339_sec[] = "%Y-%m-%dT%H:%M:%S%Ez"; + +ABSL_DLL extern const char RFC1123_full[] = + "%a, %d %b %E4Y %H:%M:%S %z"; +ABSL_DLL extern const char RFC1123_no_wday[] = + "%d %b %E4Y %H:%M:%S %z"; namespace { diff --git a/absl/time/internal/cctz/src/time_zone_fixed.cc b/absl/time/internal/cctz/src/time_zone_fixed.cc index a342e37d..303c0244 100644 --- a/absl/time/internal/cctz/src/time_zone_fixed.cc +++ b/absl/time/internal/cctz/src/time_zone_fixed.cc @@ -89,29 +89,29 @@ std::string FixedOffsetToName(const seconds& offset) { // offsets and to (somewhat) limit the total number of zones. return "UTC"; } - int seconds = static_cast(offset.count()); - const char sign = (seconds < 0 ? '-' : '+'); - int minutes = seconds / 60; - seconds %= 60; + int offset_seconds = static_cast(offset.count()); + const char sign = (offset_seconds < 0 ? '-' : '+'); + int offset_minutes = offset_seconds / 60; + offset_seconds %= 60; if (sign == '-') { - if (seconds > 0) { - seconds -= 60; - minutes += 1; + if (offset_seconds > 0) { + offset_seconds -= 60; + offset_minutes += 1; } - seconds = -seconds; - minutes = -minutes; + offset_seconds = -offset_seconds; + offset_minutes = -offset_minutes; } - int hours = minutes / 60; - minutes %= 60; + int offset_hours = offset_minutes / 60; + offset_minutes %= 60; const std::size_t prefix_len = sizeof(kFixedZonePrefix) - 1; char buf[prefix_len + sizeof("-24:00:00")]; char* ep = std::copy(kFixedZonePrefix, kFixedZonePrefix + prefix_len, buf); *ep++ = sign; - ep = Format02d(ep, hours); + ep = Format02d(ep, offset_hours); *ep++ = ':'; - ep = Format02d(ep, minutes); + ep = Format02d(ep, offset_minutes); *ep++ = ':'; - ep = Format02d(ep, seconds); + ep = Format02d(ep, offset_seconds); *ep++ = '\0'; assert(ep == buf + sizeof(buf)); return buf; diff --git a/absl/time/internal/cctz/src/time_zone_format_test.cc b/absl/time/internal/cctz/src/time_zone_format_test.cc index de75629a..caebcc4d 100644 --- a/absl/time/internal/cctz/src/time_zone_format_test.cc +++ b/absl/time/internal/cctz/src/time_zone_format_test.cc @@ -1252,9 +1252,9 @@ TEST(Parse, ExtendedSubecondsScan) { const auto expected = chrono::system_clock::from_time_t(0) + chrono::nanoseconds(micros * 1000 + ns); for (int ps = 0; ps < 1000; ps += 250) { - std::ostringstream oss; + std::ostringstream ps_oss; oss << std::setfill('0') << std::setw(3) << ps; - const std::string input = nanos + oss.str() + "999"; + const std::string input = nanos + ps_oss.str() + "999"; EXPECT_TRUE(parse("%E*f", input, tz, &tp)); EXPECT_EQ(expected + chrono::nanoseconds(ps) / 1000, tp) << input; } diff --git a/absl/time/internal/cctz/src/time_zone_info.cc b/absl/time/internal/cctz/src/time_zone_info.cc index 971542d0..f1697cdf 100644 --- a/absl/time/internal/cctz/src/time_zone_info.cc +++ b/absl/time/internal/cctz/src/time_zone_info.cc @@ -641,9 +641,9 @@ std::unique_ptr FileZoneInfoSource::Open( if (fp == nullptr) return nullptr; std::size_t length = 0; if (fseek(fp, 0, SEEK_END) == 0) { - long pos = ftell(fp); - if (pos >= 0) { - length = static_cast(pos); + long offset = ftell(fp); + if (offset >= 0) { + length = static_cast(offset); } rewind(fp); } diff --git a/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/absl/time/internal/cctz/src/time_zone_lookup_test.cc index 227b1278..99137a08 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc @@ -1028,16 +1028,17 @@ TEST(MakeTime, LocalTimeLibC) { ASSERT_EQ(0, setenv("TZ", *np, 1)); // change what "localtime" means const auto zi = local_time_zone(); const auto lc = LoadZone("libc:localtime"); - time_zone::civil_transition trans; + time_zone::civil_transition transition; for (auto tp = zi.lookup(civil_second()).trans; - zi.next_transition(tp, &trans); tp = zi.lookup(trans.to).trans) { - const auto fcl = zi.lookup(trans.from); - const auto tcl = zi.lookup(trans.to); + zi.next_transition(tp, &transition); + tp = zi.lookup(transition.to).trans) { + const auto fcl = zi.lookup(transition.from); + const auto tcl = zi.lookup(transition.to); civil_second cs; // compare cs in zi and lc if (fcl.kind == time_zone::civil_lookup::UNIQUE) { if (tcl.kind == time_zone::civil_lookup::UNIQUE) { // Both unique; must be an is_dst or abbr change. - ASSERT_EQ(trans.from, trans.to); + ASSERT_EQ(transition.from, transition.to); const auto trans = fcl.trans; const auto tal = zi.lookup(trans); const auto tprev = trans - absl::time_internal::cctz::seconds(1); @@ -1048,11 +1049,11 @@ TEST(MakeTime, LocalTimeLibC) { continue; } ASSERT_EQ(time_zone::civil_lookup::REPEATED, tcl.kind); - cs = trans.to; + cs = transition.to; } else { ASSERT_EQ(time_zone::civil_lookup::UNIQUE, tcl.kind); ASSERT_EQ(time_zone::civil_lookup::SKIPPED, fcl.kind); - cs = trans.from; + cs = transition.from; } if (cs.year() > 2037) break; // limit test time (and to 32-bit time_t) const auto cl_zi = zi.lookup(cs); diff --git a/absl/time/time.h b/absl/time/time.h index 1be5727c..33a4a630 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -527,59 +527,30 @@ std::chrono::seconds ToChronoSeconds(Duration d); std::chrono::minutes ToChronoMinutes(Duration d); std::chrono::hours ToChronoHours(Duration d); - // FormatDuration() // -// Returns a string represention of the duration in a format consisting of a -// possibly-signed prefix and a sequence of decimal numbers, each with an -// optional fractional part and a unit suffix. -// -// Valid unit suffixes are "ns", "us" "ms", "s", "m", and "h". -// -// Simple examples include "300ms", "-1.5h", and "2h45m". Returns "inf" or -// "-inf" for +/- `InfiniteDuration()` values and "0" for `ZeroDuration()` -// values. -// -// This string format is used both as an input for parsing (when handling -// command-line flags of type `absl::Duration`) and as an output in -// `FormatDuration()` +// Returns a string representing the duration in the form "72h3m0.5s". +// Returns "inf" or "-inf" for +/- `InfiniteDuration()`. std::string FormatDuration(Duration d); +// Output stream operator. +inline std::ostream& operator<<(std::ostream& os, Duration d) { + return os << FormatDuration(d); +} + // ParseDuration() // -// Parses a `dur_string` of the format noted above into an `absl::Duration` -// value. -// -// Parses "0" as a zero-length duration value. Parses "-inf" or "+inf" as -// infinite durations values. +// Parses a duration string consisting of a possibly signed sequence of +// decimal numbers, each with an optional fractional part and a unit +// suffix. The valid suffixes are "ns", "us" "ms", "s", "m", and "h". +// Simple examples include "300ms", "-1.5h", and "2h45m". Parses "0" as +// `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`. bool ParseDuration(const std::string& dur_string, Duration* d); -// AbslParseFlag() -// -// Parses the command-line flag string representation `text` (using the format -// noted above) into an `absl::Duration` destination, setting `error` on -// failure. -// -// Example: -// -// --timeout=6h30m -// --timeout=inf // Equivalent to `InfiniteDuration()` -// --timeout=0 // Equivalent to `ZeroDuration()` +// Support for flag values of type Duration. Duration flags must be specified +// in a format that is valid input for absl::ParseDuration(). bool AbslParseFlag(absl::string_view text, Duration* dst, std::string* error); - -// AbslUnparseFlag() -// -// Unparses an `absl::Duration` into a command-line string representation using -// the format noted above. std::string AbslUnparseFlag(Duration d); - -// operator<<() -// -// Output stream operator, returning a stream in the format noted above. -inline std::ostream& operator<<(std::ostream& os, Duration d) { - return os << FormatDuration(d); -} - ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const std::string& text, Duration* dst, std::string* error); ABSL_DEPRECATED("Use AbslUnparseFlag() instead.") @@ -842,29 +813,18 @@ Time FromChrono(const std::chrono::system_clock::time_point& tp); // // tp == std::chrono::system_clock::from_time_t(123); std::chrono::system_clock::time_point ToChronoTime(Time); -// AbslParseFlag() -// -// Parses the command-line flag string representation `text` into an -// `absl::Time` destination, setting `error` on failure. Time flag string -// representations must be specified in a format that matches -// `absl::RFC3339_full`. -// -// Example: +// Support for flag values of type Time. Time flags must be specified in a +// format that matches absl::RFC3339_full. For example: // // --start_time=2016-01-02T03:04:05.678+08:00 // // Note: A UTC offset (or 'Z' indicating a zero-offset from UTC) is required. // // Additionally, if you'd like to specify a time as a count of -// seconds/milliseconds/etc from the Unix epoch, use an `absl::Duration` flag -// and add that duration to `absl::UnixEpoch()` to get an `absl::Time`. +// seconds/milliseconds/etc from the Unix epoch, use an absl::Duration flag +// and add that duration to absl::UnixEpoch() to get an absl::Time. bool AbslParseFlag(absl::string_view text, Time* t, std::string* error); - -// AbslUnparseFlag() -// -// Unparses an `absl::Time` into a command-line string format as noted above. std::string AbslUnparseFlag(Time t); - ABSL_DEPRECATED("Use AbslParseFlag() instead.") bool ParseFlag(const std::string& text, Time* t, std::string* error); ABSL_DEPRECATED("Use AbslUnparseFlag() instead.") @@ -1243,15 +1203,18 @@ struct tm ToTM(Time t, TimeZone tz); // time with UTC offset. Also note the use of "%Y": RFC3339 mandates that // years have exactly four digits, but we allow them to take their natural // width. -extern const char RFC3339_full[]; // %Y-%m-%dT%H:%M:%E*S%Ez -extern const char RFC3339_sec[]; // %Y-%m-%dT%H:%M:%S%Ez +ABSL_DLL extern const char + RFC3339_full[]; // %Y-%m-%dT%H:%M:%E*S%Ez +ABSL_DLL extern const char RFC3339_sec[]; // %Y-%m-%dT%H:%M:%S%Ez // RFC1123_full // RFC1123_no_wday // // FormatTime()/ParseTime() format specifiers for RFC1123 date/time strings. -extern const char RFC1123_full[]; // %a, %d %b %E4Y %H:%M:%S %z -extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z +ABSL_DLL extern const char + RFC1123_full[]; // %a, %d %b %E4Y %H:%M:%S %z +ABSL_DLL extern const char + RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z // FormatTime() // -- cgit v1.2.3 From c44657f55692eddf5504156645d1f4ec7b3acabd Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 13 Feb 2020 06:52:24 -0800 Subject: Export of internal Abseil changes -- dc6d2715f0415082fcc8da8bf74e74bce69b236c by Derek Mauro : Correctly detect C++ exceptions support on Clang for Windows PiperOrigin-RevId: 294905116 -- b43c44501b4820f4a2f396e426619bd02565707e by Derek Mauro : Set CMAKE_CXX_STANDARD on the MacOS CMake build PiperOrigin-RevId: 294730418 -- 184a078649167f9738da60b0f12108256bcfd67b by Abseil Team : No need for custom spec to deal with limited platforms. PiperOrigin-RevId: 294700133 -- b437c7f659b809fc84a45eab284265fec497a3e3 by Abseil Team : Not calling sigaltstack on WatchOS and TVOS since they don't allow it. PiperOrigin-RevId: 294699951 -- 23ab8dd381ee4104125dece8455bc96b81239789 by Gennadiy Rozental : Replace use of atomic+global Mutex+bool with absl::call_once for Flag initialization. This simplifies the initialization logic and helps with upcoming work with value storage rework. PiperOrigin-RevId: 294654938 -- cee576163a2753c6138bc254e81de4800ea3307a by Gennadiy Rozental : Separate const bits from mutable bits. Since bit field is not atomic unit for reading/writing, we can't have constant bits which are not protected by data guard to share the space with mutable bits which are protected. This CL just reorder fields in class and does not make any other changes. PiperOrigin-RevId: 294501780 -- b4d0e2ab559d04f655c93f008594562234773c15 by Abseil Team : Correct the comment. PiperOrigin-RevId: 294499328 -- a788cf71af6247df033298c49939ba0414d71693 by Derek Mauro : Move the FAQ to the top level directory PiperOrigin-RevId: 294493863 GitOrigin-RevId: dc6d2715f0415082fcc8da8bf74e74bce69b236c Change-Id: I71b0d8cd401b48d41433417858ae0d69398b6602 --- FAQ.md | 144 +++++++++++++++++++++++++++++++ absl/FAQ.md | 144 ------------------------------- absl/abseil.podspec.gen.py | 18 ---- absl/base/config.h | 14 ++- absl/container/node_hash_set.h | 4 +- absl/debugging/failure_signal_handler.cc | 13 ++- absl/flags/BUILD.bazel | 1 + absl/flags/CMakeLists.txt | 1 + absl/flags/internal/flag.cc | 29 ++----- absl/flags/internal/flag.h | 19 ++-- ci/macos_xcode_cmake.sh | 1 + 11 files changed, 188 insertions(+), 200 deletions(-) create mode 100644 FAQ.md delete mode 100644 absl/FAQ.md (limited to 'absl/base/config.h') diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 00000000..af721307 --- /dev/null +++ b/FAQ.md @@ -0,0 +1,144 @@ +# Abseil FAQ + +## Is Abseil the right home for my utility library? + +Most often the answer to the question is "no." As both the [About +Abseil](https://abseil.io/about/) page and our [contributing +guidelines](https://github.com/abseil/abseil-cpp/blob/master/CONTRIBUTING.md#contribution-guidelines) +explain, Abseil contains a variety of core C++ library code that is widely used +at [Google](https://www.google.com/). As such, Abseil's primary purpose is to be +used as a dependency by Google's open source C++ projects. While we do hope that +Abseil is also useful to the C++ community at large, this added constraint also +means that we are unlikely to accept a contribution of utility code that isn't +already widely used by Google. + +## How to I set the C++ dialect used to build Abseil? + +The short answer is that whatever mechanism you choose, you need to make sure +that you set this option consistently at the global level for your entire +project. If, for example, you want to set the C++ dialect to C++17, with +[Bazel](https://bazel/build/) as the build system and `gcc` or `clang` as the +compiler, there several ways to do this: +* Pass `--cxxopt=-std=c++17` on the command line (for example, `bazel build + --cxxopt=-std=c++17 ...`) +* Set the environment variable `BAZEL_CXXOPTS` (for example, + `BAZEL_CXXOPTS=-std=c++17`) +* Add `build --cxxopt=-std=c++17` to your [`.bazelrc` + file](https://docs.bazel.build/versions/master/guide.html#bazelrc) + +If you are using CMake as the build system, you'll need to add a line like +`set(CMAKE_CXX_STANDARD 17)` to your top level `CMakeLists.txt` file. See the +[CMake build +instructions](https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md) +for more information. + +For a longer answer to this question and to understand why some other approaches +don't work, see the answer to "What is ABI and why don't you recommend using a +pre-compiled version of Abseil?" + +## What is ABI and why don't you recommend using a pre-compiled version of Abseil? + +For the purposes of this discussion, you can think of +[ABI](https://en.wikipedia.org/wiki/Application_binary_interface) as the +compiled representation of the interfaces in code. This is in contrast to +[API](https://en.wikipedia.org/wiki/Application_programming_interface), which +you can think of as the interfaces as defined by the code itself. [Abseil has a +strong promise of API compatibility, but does not make any promise of ABI +compatibility](https://abseil.io/about/compatibility). Let's take a look at what +this means in practice. + +You might be tempted to do something like this in a +[Bazel](https://bazel.build/) `BUILD` file: + +``` +# DON'T DO THIS!!! +cc_library( + name = "my_library", + srcs = ["my_library.cc"], + copts = ["-std=c++17"], # May create a mixed-mode compile! + deps = ["@com_google_absl//absl/strings"], +) +``` + +Applying `-std=c++17` to an individual target in your `BUILD` file is going to +compile that specific target in C++17 mode, but it isn't going to ensure the +Abseil library is built in C++17 mode, since the Abseil library itself is a +different build target. If your code includes an Abseil header, then your +program may contain conflicting definitions of the same +class/function/variable/enum, etc. As a rule, all compile options that affect +the ABI of a program need to be applied to the entire build on a global basis. + +C++ has something called the [One Definition +Rule](https://en.wikipedia.org/wiki/One_Definition_Rule) (ODR). C++ doesn't +allow multiple definitions of the same class/function/variable/enum, etc. ODR +violations sometimes result in linker errors, but linkers do not always catch +violations. Uncaught ODR violations can result in strange runtime behaviors or +crashes that can be hard to debug. + +If you build the Abseil library and your code using different compile options +that affect ABI, there is a good chance you will run afoul of the One Definition +Rule. Examples of GCC compile options that affect ABI include (but aren't +limited to) language dialect (e.g. `-std=`), optimization level (e.g. `-O2`), +code generation flags (e.g. `-fexceptions`), and preprocessor defines +(e.g. `-DNDEBUG`). + +If you use a pre-compiled version of Abseil, (for example, from your Linux +distribution package manager or from something like +[vcpkg](https://github.com/microsoft/vcpkg)) you have to be very careful to +ensure ABI compatibility across the components of your program. The only way you +can be sure your program is going to be correct regarding ABI is to ensure +you've used the exact same compile options as were used to build the +pre-compiled library. This does not mean that Abseil cannot work as part of a +Linux distribution since a knowledgeable binary packager will have ensured that +all packages have been built with consistent compile options. This is one of the +reasons we warn against - though do not outright reject - using Abseil as a +pre-compiled library. + +Another possible way that you might afoul of ABI issues is if you accidentally +include two versions of Abseil in your program. Multiple versions of Abseil can +end up within the same binary if your program uses the Abseil library and +another library also transitively depends on Abseil (resulting in what is +sometimes called the diamond dependency problem). In cases such as this you must +structure your build so that all libraries use the same version of Abseil. +[Abseil's strong promise of API compatibility between +releases](https://abseil.io/about/compatibility) means the latest "HEAD" release +of Abseil is almost certainly the right choice if you are doing as we recommend +and building all of your code from source. + +For these reasons we recommend you avoid pre-compiled code and build the Abseil +library yourself in a consistent manner with the rest of your code. + +## What is "live at head" and how do I do it? + +From Abseil's point-of-view, "live at head" means that every Abseil source +release (which happens on an almost daily basis) is either API compatible with +the previous release, or comes with an automated tool that you can run over code +to make it compatible. In practice, the need to use an automated tool is +extremely rare. This means that upgrading from one source release to another +should be a routine practice that can and should be performed often. + +We recommend you update to the latest release of Abseil as often as +possible. Not only will you pick up bug fixes more quickly, but if you have good +automated testing, you will catch and be able to fix any [Hyrum's +Law](https://www.hyrumslaw.com/) dependency problems on an incremental basis +instead of being overwhelmed by them and having difficulty isolating them if you +wait longer between updates. + +If you are using the [Bazel](https://bazel.build/) build system and its +[external dependencies](https://docs.bazel.build/versions/master/external.html) +feature, updating the +[`http_archive`](https://docs.bazel.build/versions/master/repo/http.html#http_archive) +rule in your +[`WORKSPACE`](https://docs.bazel.build/versions/master/be/workspace.html) for +`com_google_abseil` to point to the latest release is all you need to do. You +can commit the updated `WORKSPACE` file to your source control every time you +update, and if you have good automated testing, you might even consider +automating this. + +One thing we don't recommend is using GitHub's `master.zip` files (for example +[https://github.com/abseil/abseil-cpp/archive/master.zip](https://github.com/abseil/abseil-cpp/archive/master.zip)), +which are always the latest commit in the `master` branch, to implement live at +head. Since these `master.zip` URLs are not versioned, you will lose build +reproducibility. In addition, some build systems, including Bazel, will simply +cache this file, which means you won't actually be updating to the latest +release until your cache is cleared or invalidated. diff --git a/absl/FAQ.md b/absl/FAQ.md deleted file mode 100644 index af721307..00000000 --- a/absl/FAQ.md +++ /dev/null @@ -1,144 +0,0 @@ -# Abseil FAQ - -## Is Abseil the right home for my utility library? - -Most often the answer to the question is "no." As both the [About -Abseil](https://abseil.io/about/) page and our [contributing -guidelines](https://github.com/abseil/abseil-cpp/blob/master/CONTRIBUTING.md#contribution-guidelines) -explain, Abseil contains a variety of core C++ library code that is widely used -at [Google](https://www.google.com/). As such, Abseil's primary purpose is to be -used as a dependency by Google's open source C++ projects. While we do hope that -Abseil is also useful to the C++ community at large, this added constraint also -means that we are unlikely to accept a contribution of utility code that isn't -already widely used by Google. - -## How to I set the C++ dialect used to build Abseil? - -The short answer is that whatever mechanism you choose, you need to make sure -that you set this option consistently at the global level for your entire -project. If, for example, you want to set the C++ dialect to C++17, with -[Bazel](https://bazel/build/) as the build system and `gcc` or `clang` as the -compiler, there several ways to do this: -* Pass `--cxxopt=-std=c++17` on the command line (for example, `bazel build - --cxxopt=-std=c++17 ...`) -* Set the environment variable `BAZEL_CXXOPTS` (for example, - `BAZEL_CXXOPTS=-std=c++17`) -* Add `build --cxxopt=-std=c++17` to your [`.bazelrc` - file](https://docs.bazel.build/versions/master/guide.html#bazelrc) - -If you are using CMake as the build system, you'll need to add a line like -`set(CMAKE_CXX_STANDARD 17)` to your top level `CMakeLists.txt` file. See the -[CMake build -instructions](https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md) -for more information. - -For a longer answer to this question and to understand why some other approaches -don't work, see the answer to "What is ABI and why don't you recommend using a -pre-compiled version of Abseil?" - -## What is ABI and why don't you recommend using a pre-compiled version of Abseil? - -For the purposes of this discussion, you can think of -[ABI](https://en.wikipedia.org/wiki/Application_binary_interface) as the -compiled representation of the interfaces in code. This is in contrast to -[API](https://en.wikipedia.org/wiki/Application_programming_interface), which -you can think of as the interfaces as defined by the code itself. [Abseil has a -strong promise of API compatibility, but does not make any promise of ABI -compatibility](https://abseil.io/about/compatibility). Let's take a look at what -this means in practice. - -You might be tempted to do something like this in a -[Bazel](https://bazel.build/) `BUILD` file: - -``` -# DON'T DO THIS!!! -cc_library( - name = "my_library", - srcs = ["my_library.cc"], - copts = ["-std=c++17"], # May create a mixed-mode compile! - deps = ["@com_google_absl//absl/strings"], -) -``` - -Applying `-std=c++17` to an individual target in your `BUILD` file is going to -compile that specific target in C++17 mode, but it isn't going to ensure the -Abseil library is built in C++17 mode, since the Abseil library itself is a -different build target. If your code includes an Abseil header, then your -program may contain conflicting definitions of the same -class/function/variable/enum, etc. As a rule, all compile options that affect -the ABI of a program need to be applied to the entire build on a global basis. - -C++ has something called the [One Definition -Rule](https://en.wikipedia.org/wiki/One_Definition_Rule) (ODR). C++ doesn't -allow multiple definitions of the same class/function/variable/enum, etc. ODR -violations sometimes result in linker errors, but linkers do not always catch -violations. Uncaught ODR violations can result in strange runtime behaviors or -crashes that can be hard to debug. - -If you build the Abseil library and your code using different compile options -that affect ABI, there is a good chance you will run afoul of the One Definition -Rule. Examples of GCC compile options that affect ABI include (but aren't -limited to) language dialect (e.g. `-std=`), optimization level (e.g. `-O2`), -code generation flags (e.g. `-fexceptions`), and preprocessor defines -(e.g. `-DNDEBUG`). - -If you use a pre-compiled version of Abseil, (for example, from your Linux -distribution package manager or from something like -[vcpkg](https://github.com/microsoft/vcpkg)) you have to be very careful to -ensure ABI compatibility across the components of your program. The only way you -can be sure your program is going to be correct regarding ABI is to ensure -you've used the exact same compile options as were used to build the -pre-compiled library. This does not mean that Abseil cannot work as part of a -Linux distribution since a knowledgeable binary packager will have ensured that -all packages have been built with consistent compile options. This is one of the -reasons we warn against - though do not outright reject - using Abseil as a -pre-compiled library. - -Another possible way that you might afoul of ABI issues is if you accidentally -include two versions of Abseil in your program. Multiple versions of Abseil can -end up within the same binary if your program uses the Abseil library and -another library also transitively depends on Abseil (resulting in what is -sometimes called the diamond dependency problem). In cases such as this you must -structure your build so that all libraries use the same version of Abseil. -[Abseil's strong promise of API compatibility between -releases](https://abseil.io/about/compatibility) means the latest "HEAD" release -of Abseil is almost certainly the right choice if you are doing as we recommend -and building all of your code from source. - -For these reasons we recommend you avoid pre-compiled code and build the Abseil -library yourself in a consistent manner with the rest of your code. - -## What is "live at head" and how do I do it? - -From Abseil's point-of-view, "live at head" means that every Abseil source -release (which happens on an almost daily basis) is either API compatible with -the previous release, or comes with an automated tool that you can run over code -to make it compatible. In practice, the need to use an automated tool is -extremely rare. This means that upgrading from one source release to another -should be a routine practice that can and should be performed often. - -We recommend you update to the latest release of Abseil as often as -possible. Not only will you pick up bug fixes more quickly, but if you have good -automated testing, you will catch and be able to fix any [Hyrum's -Law](https://www.hyrumslaw.com/) dependency problems on an incremental basis -instead of being overwhelmed by them and having difficulty isolating them if you -wait longer between updates. - -If you are using the [Bazel](https://bazel.build/) build system and its -[external dependencies](https://docs.bazel.build/versions/master/external.html) -feature, updating the -[`http_archive`](https://docs.bazel.build/versions/master/repo/http.html#http_archive) -rule in your -[`WORKSPACE`](https://docs.bazel.build/versions/master/be/workspace.html) for -`com_google_abseil` to point to the latest release is all you need to do. You -can commit the updated `WORKSPACE` file to your source control every time you -update, and if you have good automated testing, you might even consider -automating this. - -One thing we don't recommend is using GitHub's `master.zip` files (for example -[https://github.com/abseil/abseil-cpp/archive/master.zip](https://github.com/abseil/abseil-cpp/archive/master.zip)), -which are always the latest commit in the `master` branch, to implement live at -head. Since these `master.zip` URLs are not versioned, you will lose build -reproducibility. In addition, some build systems, including Bazel, will simply -cache this file, which means you won't actually be updating to the latest -release until your cache is cleared or invalidated. diff --git a/absl/abseil.podspec.gen.py b/absl/abseil.podspec.gen.py index 2bf153c0..6aefb794 100755 --- a/absl/abseil.podspec.gen.py +++ b/absl/abseil.podspec.gen.py @@ -46,18 +46,6 @@ Pod::Spec.new do |s| s.watchos.deployment_target = '2.0' """ -# Limited platforms that abseil supports. -# This is mainly because of sigaltstack unavailable on watchOS. -LIMITED_SUPPORT_PLATFORMS = [ - "ios.deployment_target = '7.0'", - "osx.deployment_target = '10.9'", -] - -# Custom specification per rule. -CUSTOM_SPEC_MAP = { - "//absl/debugging:failure_signal_handler": LIMITED_SUPPORT_PLATFORMS, -} - # Rule object representing the rule of Bazel BUILD. Rule = collections.namedtuple( "Rule", "type name package srcs hdrs textual_hdrs deps visibility testonly") @@ -200,12 +188,6 @@ def write_podspec_rule(f, rule, depth): name = get_spec_name(dep.replace(":", "/")) f.write("{indent}{var}.dependency '{dep}'\n".format( indent=indent, var=spec_var, dep=name)) - # Writes custom specification. - custom_spec = CUSTOM_SPEC_MAP.get(rule.package + ":" + rule.name) - if custom_spec: - for spec in custom_spec: - f.write("{indent}{var}.{spec}\n".format( - indent=indent, var=spec_var, spec=spec)) def write_indented_list(f, leading, values): diff --git a/absl/base/config.h b/absl/base/config.h index eac5d268..ee99f946 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -316,13 +316,19 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #error ABSL_HAVE_EXCEPTIONS cannot be directly set. #elif defined(__clang__) -// TODO(calabrese) -// Switch to using __cpp_exceptions when we no longer support versions < 3.6. -// For details on this check, see: -// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro + +#if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6) +// Clang >= 3.6 +#if __has_feature(cxx_exceptions) +#define ABSL_HAVE_EXCEPTIONS 1 +#endif // __has_feature(cxx_exceptions) +#else +// Clang < 3.6 +// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro #if defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) #define ABSL_HAVE_EXCEPTIONS 1 #endif // defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) +#endif // __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6) // Handle remaining special cases and default to exceptions being supported. #elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h index 0e2dee54..ad54b6dc 100644 --- a/absl/container/node_hash_set.h +++ b/absl/container/node_hash_set.h @@ -77,7 +77,7 @@ struct NodeHashSetPolicy; // // // Create a node hash set of three strings // absl::node_hash_map ducks = -// {"huey", "dewey"}, "louie"}; +// {"huey", "dewey", "louie"}; // // // Insert a new element into the node hash map // ducks.insert("donald"}; @@ -111,7 +111,7 @@ class node_hash_set // * Initializer List constructor // // absl::node_hash_set set2 = - // {{"huey"}, {"dewey"}, {"louie"},}; + // {{"huey"}, {"dewey"}, {"louie"}}; // // * Copy constructor // diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc index 470d6768..cd141ecf 100644 --- a/absl/debugging/failure_signal_handler.cc +++ b/absl/debugging/failure_signal_handler.cc @@ -24,6 +24,10 @@ #include #endif +#ifdef __APPLE__ +#include +#endif + #ifdef ABSL_HAVE_MMAP #include #endif @@ -44,6 +48,11 @@ #ifndef _WIN32 #define ABSL_HAVE_SIGACTION +// Apple WatchOS and TVOS don't allow sigaltstack +#if !(defined(TARGET_OS_WATCH) && TARGET_OS_WATCH) && \ + !(defined(TARGET_OS_TV) && TARGET_OS_TV) +#define ABSL_HAVE_SIGALTSTACK +#endif #endif namespace absl { @@ -117,7 +126,7 @@ const char* FailureSignalToString(int signo) { } // namespace debugging_internal -#ifndef _WIN32 +#ifdef ABSL_HAVE_SIGALTSTACK static bool SetupAlternateStackOnce() { #if defined(__wasm__) || defined (__asjms__) @@ -169,7 +178,7 @@ static bool SetupAlternateStackOnce() { // Returns the appropriate flag for sig_action.sa_flags // if the system supports using an alternate stack. static int MaybeSetupAlternateStack() { -#ifndef _WIN32 +#ifdef ABSL_HAVE_SIGALTSTACK ABSL_ATTRIBUTE_UNUSED static const bool kOnce = SetupAlternateStackOnce(); return SA_ONSTACK; #else diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index d2ca5c6f..cdb4e7e8 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -41,6 +41,7 @@ cc_library( ":config", ":handle", ":registry", + "//absl/base", "//absl/base:config", "//absl/base:core_headers", "//absl/memory", diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt index 20e66825..1d25f0de 100644 --- a/absl/flags/CMakeLists.txt +++ b/absl/flags/CMakeLists.txt @@ -27,6 +27,7 @@ absl_cc_library( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS + absl::base absl::config absl::flags_config absl::flags_handle diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc index ba70da91..721e411e 100644 --- a/absl/flags/internal/flag.cc +++ b/absl/flags/internal/flag.cc @@ -80,41 +80,22 @@ class MutexRelock { absl::Mutex* mu_; }; -// This global lock guards the initialization and destruction of data_guard_, -// which is used to guard the other Flag data. -ABSL_CONST_INIT static absl::Mutex flag_mutex_lifetime_guard(absl::kConstInit); - } // namespace void FlagImpl::Init() { - { - absl::MutexLock lock(&flag_mutex_lifetime_guard); - - // Must initialize data guard for this flag. - if (!is_data_guard_inited_) { - new (&data_guard_) absl::Mutex; - is_data_guard_inited_ = true; - } - } + new (&data_guard_) absl::Mutex; absl::MutexLock lock(reinterpret_cast(&data_guard_)); - if (value_.dynamic != nullptr) { - inited_.store(true, std::memory_order_release); - } else { - // Need to initialize cur field. - value_.dynamic = MakeInitValue().release(); - StoreAtomic(); - inited_.store(true, std::memory_order_release); - } + value_.dynamic = MakeInitValue().release(); + StoreAtomic(); } // Ensures that the lazily initialized data is initialized, // and returns pointer to the mutex guarding flags data. absl::Mutex* FlagImpl::DataGuard() const { - if (ABSL_PREDICT_FALSE(!inited_.load(std::memory_order_acquire))) { - const_cast(this)->Init(); - } + absl::call_once(const_cast(this)->init_control_, &FlagImpl::Init, + const_cast(this)); // data_guard_ is initialized. return reinterpret_cast(&data_guard_); diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index ef30a22f..b426ccb5 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -24,6 +24,7 @@ #include #include +#include "absl/base/call_once.h" #include "absl/base/config.h" #include "absl/base/thread_annotations.h" #include "absl/flags/config.h" @@ -281,10 +282,8 @@ class FlagImpl { help_(help.source), help_source_kind_(static_cast(help.kind)), def_kind_(static_cast(FlagDefaultKind::kGenFunc)), - is_data_guard_inited_(false), modified_(false), on_command_line_(false), - inited_(false), counter_(0), callback_(nullptr), default_src_(default_value_gen), @@ -406,20 +405,28 @@ class FlagImpl { // Indicates if help message was supplied as literal or generator func. const uint8_t help_source_kind_ : 1; + // ------------------------------------------------------------------------ + // The bytes containing the const bitfields must not be shared with bytes + // containing the mutable bitfields. + // ------------------------------------------------------------------------ + + // Unique tag for absl::call_once call to initialize this flag. + // + // The placement of this variable between the immutable and mutable bitfields + // is important as prevents them from occupying the same byte. If you remove + // this variable, make sure to maintain this property. + absl::once_flag init_control_; + // Mutable flag's state (guarded by `data_guard_`). // If def_kind_ == kDynamicValue, default_src_ holds a dynamically allocated // value. uint8_t def_kind_ : 1 ABSL_GUARDED_BY(*DataGuard()); - // Protects against multiple concurrent constructions of `data_guard_`. - bool is_data_guard_inited_ : 1; // Has this flag's value been modified? bool modified_ : 1 ABSL_GUARDED_BY(*DataGuard()); // Has this flag been specified on command line. bool on_command_line_ : 1 ABSL_GUARDED_BY(*DataGuard()); - // Indicates that the flag state is initialized. - std::atomic inited_; // Mutation counter int64_t counter_ ABSL_GUARDED_BY(*DataGuard()); // Optional flag's callback and absl::Mutex to guard the invocations. diff --git a/ci/macos_xcode_cmake.sh b/ci/macos_xcode_cmake.sh index 75b0f2d1..a1f4a857 100755 --- a/ci/macos_xcode_cmake.sh +++ b/ci/macos_xcode_cmake.sh @@ -36,6 +36,7 @@ for compilation_mode in ${ABSL_CMAKE_BUILD_TYPES}; do time cmake ${ABSEIL_ROOT} \ -GXcode \ -DCMAKE_BUILD_TYPE=${compilation_mode} \ + -DCMAKE_CXX_STANDARD=11 \ -DABSL_USE_GOOGLETEST_HEAD=ON \ -DABSL_RUN_TESTS=ON time cmake --build . -- cgit v1.2.3 From 7853a7586c492ce8905c9e49f8679dada6354f2c Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 16 Mar 2020 09:06:23 -0700 Subject: Export of internal Abseil changes -- 91ca367a7548270155721bdda74611aeea2a2153 by Abseil Team : Replace the only usage of btree_node::swap with simpler logic using transfers and delete btree_node::swap. Add a benchmark for constructing small containers. PiperOrigin-RevId: 301169874 -- ff9d73a7125b7f8ab5733cda877204dfbfac138e by Derek Mauro : Ensure ABSL_CXX_STANDARD is set. Fixes #640 PiperOrigin-RevId: 301160106 -- 14ca0beee8c109e532134e7e9da7b072da1bf911 by Abseil Team : Rollback the change to make Cord iterators a fixed size. That change increased the iterator size, which can cause a deep recursion call to hit the stack memory limit, in turn causing a signal 11 failure. PiperOrigin-RevId: 301084915 -- 619e3cd9e56408bdb8b3b5a1e08dda1e95242264 by Matthew Brown : Internal Change PiperOrigin-RevId: 300832828 -- 64f8d62ab4c4c78077dbe85a9595a8eeb6d16608 by Gennadiy Rozental : Fix for empty braces support. We will call proper aggregate construction in case when {} is used as default value. In other words instead of "new T", we'll call "new T{}". PiperOrigin-RevId: 300715686 -- db3f65594d6db8b104b01262f884dff465b696ef by Abseil Team : Emscripten supports thread-local storage nowadays. PiperOrigin-RevId: 300675185 GitOrigin-RevId: 91ca367a7548270155721bdda74611aeea2a2153 Change-Id: I3344f745f9c3fc78775532b1808442fabd98e34a --- absl/base/config.h | 7 - absl/container/btree_benchmark.cc | 22 +++ absl/container/internal/btree.h | 76 +++----- absl/copts/AbseilConfigureCopts.cmake | 2 + absl/flags/flag_test.cc | 67 +++++++ absl/flags/internal/flag.h | 2 +- absl/strings/cord.cc | 249 ++++++++++++++------------- absl/strings/cord.h | 53 +----- absl/strings/cord_test.cc | 47 ----- absl/strings/internal/str_format/extension.h | 16 +- absl/strings/str_format.h | 2 +- ci/macos_xcode_cmake.sh | 2 +- 12 files changed, 258 insertions(+), 287 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index ee99f946..f54466de 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -262,13 +262,6 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #endif #endif // defined(__ANDROID__) && defined(__clang__) -// Emscripten doesn't yet support `thread_local` or `__thread`. -// https://github.com/emscripten-core/emscripten/issues/3502 -#if defined(__EMSCRIPTEN__) -#undef ABSL_HAVE_TLS -#undef ABSL_HAVE_THREAD_LOCAL -#endif // defined(__EMSCRIPTEN__) - // ABSL_HAVE_INTRINSIC_INT128 // // Checks whether the __int128 compiler extension for a 128-bit integral type is diff --git a/absl/container/btree_benchmark.cc b/absl/container/btree_benchmark.cc index ca4d575c..46798676 100644 --- a/absl/container/btree_benchmark.cc +++ b/absl/container/btree_benchmark.cc @@ -134,6 +134,27 @@ void BM_InsertEnd(benchmark::State& state) { } } +// Benchmark inserting the first few elements in a container. In b-tree, this is +// when the root node grows. +template +void BM_InsertSmall(benchmark::State& state) { + using V = typename remove_pair_const::type; + + const int kSize = 8; + std::vector values = GenerateValues(kSize); + T container; + + while (state.KeepRunningBatch(kSize)) { + for (int i = 0; i < kSize; ++i) { + benchmark::DoNotOptimize(container.insert(values[i])); + } + state.PauseTiming(); + // Do not measure the time it takes to clear the container. + container.clear(); + state.ResumeTiming(); + } +} + template void BM_LookupImpl(benchmark::State& state, bool sorted) { using V = typename remove_pair_const::type; @@ -493,6 +514,7 @@ BTREE_TYPES(Time); MY_BENCHMARK4(type, Insert); \ MY_BENCHMARK4(type, InsertSorted); \ MY_BENCHMARK4(type, InsertEnd); \ + MY_BENCHMARK4(type, InsertSmall); \ MY_BENCHMARK4(type, Lookup); \ MY_BENCHMARK4(type, FullLookup); \ MY_BENCHMARK4(type, Delete); \ diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h index d986f81e..adf49f81 100644 --- a/absl/container/internal/btree.h +++ b/absl/container/internal/btree.h @@ -776,9 +776,6 @@ class btree_node { // delimiting key in the parent node onto itself. void merge(btree_node *src, allocator_type *alloc); - // Swaps the contents of `this` and `other`. - void swap(btree_node *other, allocator_type *alloc); - // Node allocation/deletion routines. void init_leaf(btree_node *parent, int max_count) { set_parent(parent); @@ -820,6 +817,14 @@ class btree_node { absl::container_internal::SanitizerPoisonObject(slot(i)); } + // Transfers value from slot `src_i` in `src` to slot `dest_i` in `this`. + void transfer(const size_type dest_i, const size_type src_i, btree_node *src, + allocator_type *alloc) { + absl::container_internal::SanitizerUnpoisonObject(slot(dest_i)); + params_type::transfer(alloc, slot(dest_i), src->slot(src_i)); + absl::container_internal::SanitizerPoisonObject(src->slot(src_i)); + } + // Move n values starting at value i in this node into the values starting at // value j in dest_node. void uninitialized_move_n(const size_type n, const size_type i, @@ -1752,54 +1757,6 @@ void btree_node

::merge(btree_node *src, allocator_type *alloc) { parent()->remove_value(position(), alloc); } -template -void btree_node

::swap(btree_node *other, allocator_type *alloc) { - using std::swap; - assert(leaf() == other->leaf()); - - // Determine which is the smaller/larger node. - btree_node *smaller = this, *larger = other; - if (smaller->count() > larger->count()) { - swap(smaller, larger); - } - - // Swap the values. - for (slot_type *a = smaller->start_slot(), *b = larger->start_slot(), - *end = smaller->finish_slot(); - a != end; ++a, ++b) { - params_type::swap(alloc, a, b); - } - - // Move values that can't be swapped. - const size_type to_move = larger->count() - smaller->count(); - larger->uninitialized_move_n(to_move, smaller->finish(), smaller->finish(), - smaller, alloc); - larger->value_destroy_n(smaller->finish(), to_move, alloc); - - if (!leaf()) { - // Swap the child pointers. - std::swap_ranges(&smaller->mutable_child(smaller->start()), - &smaller->mutable_child(smaller->finish() + 1), - &larger->mutable_child(larger->start())); - // Update swapped children's parent pointers. - int i = smaller->start(); - int j = larger->start(); - for (; i <= smaller->finish(); ++i, ++j) { - smaller->child(i)->set_parent(smaller); - larger->child(j)->set_parent(larger); - } - // Move the child pointers that couldn't be swapped. - for (; j <= larger->finish(); ++i, ++j) { - smaller->init_child(i, larger->child(j)); - larger->clear_child(j); - } - } - - // Swap the `finish`s. - // TODO(ezb): with floating storage, will also need to swap starts. - swap(mutable_finish(), other->mutable_finish()); -} - //// // btree_iterator methods template @@ -2492,6 +2449,7 @@ inline auto btree

::internal_emplace(iterator iter, Args &&... args) ++iter.position; } const int max_count = iter.node->max_count(); + allocator_type *alloc = mutable_allocator(); if (iter.node->count() == max_count) { // Make room in the leaf for the new item. if (max_count < kNodeValues) { @@ -2500,15 +2458,21 @@ inline auto btree

::internal_emplace(iterator iter, Args &&... args) assert(iter.node == root()); iter.node = new_leaf_root_node((std::min)(kNodeValues, 2 * max_count)); - iter.node->swap(root(), mutable_allocator()); - delete_leaf_node(root()); - mutable_root() = rightmost_ = iter.node; + // Transfer the values from the old root to the new root. + node_type *old_root = root(); + node_type *new_root = iter.node; + for (int i = old_root->start(), f = old_root->finish(); i < f; ++i) { + new_root->transfer(i, i, old_root, alloc); + } + new_root->set_finish(old_root->finish()); + old_root->set_finish(old_root->start()); + delete_leaf_node(old_root); + mutable_root() = rightmost_ = new_root; } else { rebalance_or_split(&iter); } } - iter.node->emplace_value(iter.position, mutable_allocator(), - std::forward(args)...); + iter.node->emplace_value(iter.position, alloc, std::forward(args)...); ++size_; return iter; } diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake index 390a07a0..9557e36f 100644 --- a/absl/copts/AbseilConfigureCopts.cmake +++ b/absl/copts/AbseilConfigureCopts.cmake @@ -63,3 +63,5 @@ else() set(ABSL_DEFAULT_COPTS "") set(ABSL_TEST_COPTS "") endif() + +set(ABSL_CXX_STANDARD "${CMAKE_CXX_STANDARD}") diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc index 1e01b49c..3a025576 100644 --- a/absl/flags/flag_test.cc +++ b/absl/flags/flag_test.cc @@ -293,6 +293,18 @@ TEST_F(FlagTest, TestFlagDefinition) { // -------------------------------------------------------------------- TEST_F(FlagTest, TestDefault) { + EXPECT_EQ(FLAGS_test_flag_01.DefaultValue(), "true"); + EXPECT_EQ(FLAGS_test_flag_02.DefaultValue(), "1234"); + EXPECT_EQ(FLAGS_test_flag_03.DefaultValue(), "-34"); + EXPECT_EQ(FLAGS_test_flag_04.DefaultValue(), "189"); + EXPECT_EQ(FLAGS_test_flag_05.DefaultValue(), "10765"); + EXPECT_EQ(FLAGS_test_flag_06.DefaultValue(), "40000"); + EXPECT_EQ(FLAGS_test_flag_07.DefaultValue(), "-1234567"); + EXPECT_EQ(FLAGS_test_flag_08.DefaultValue(), "9876543"); + EXPECT_EQ(FLAGS_test_flag_09.DefaultValue(), "-9.876e-50"); + EXPECT_EQ(FLAGS_test_flag_10.DefaultValue(), "1.234e+12"); + EXPECT_EQ(FLAGS_test_flag_11.DefaultValue(), ""); + EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), true); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_02), 1234); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_03), -34); @@ -308,6 +320,61 @@ TEST_F(FlagTest, TestDefault) { // -------------------------------------------------------------------- +struct NonTriviallyCopyableAggregate { + NonTriviallyCopyableAggregate() = default; + NonTriviallyCopyableAggregate(const NonTriviallyCopyableAggregate& rhs) + : value(rhs.value) {} + NonTriviallyCopyableAggregate& operator=( + const NonTriviallyCopyableAggregate& rhs) { + value = rhs.value; + return *this; + } + + int value; +}; +bool AbslParseFlag(absl::string_view src, NonTriviallyCopyableAggregate* f, + std::string* e) { + return absl::ParseFlag(src, &f->value, e); +} +std::string AbslUnparseFlag(const NonTriviallyCopyableAggregate& ntc) { + return absl::StrCat(ntc.value); +} + +bool operator==(const NonTriviallyCopyableAggregate& ntc1, + const NonTriviallyCopyableAggregate& ntc2) { + return ntc1.value == ntc2.value; +} + +} // namespace + +ABSL_FLAG(bool, test_flag_eb_01, {}, ""); +ABSL_FLAG(int32_t, test_flag_eb_02, {}, ""); +ABSL_FLAG(int64_t, test_flag_eb_03, {}, ""); +ABSL_FLAG(double, test_flag_eb_04, {}, ""); +ABSL_FLAG(std::string, test_flag_eb_05, {}, ""); +ABSL_FLAG(NonTriviallyCopyableAggregate, test_flag_eb_06, {}, ""); + +namespace { + +TEST_F(FlagTest, TestEmptyBracesDefault) { + EXPECT_EQ(FLAGS_test_flag_eb_01.DefaultValue(), "false"); + EXPECT_EQ(FLAGS_test_flag_eb_02.DefaultValue(), "0"); + EXPECT_EQ(FLAGS_test_flag_eb_03.DefaultValue(), "0"); + EXPECT_EQ(FLAGS_test_flag_eb_04.DefaultValue(), "0"); + EXPECT_EQ(FLAGS_test_flag_eb_05.DefaultValue(), ""); + EXPECT_EQ(FLAGS_test_flag_eb_06.DefaultValue(), "0"); + + EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_01), false); + EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_02), 0); + EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_03), 0); + EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_04), 0.0); + EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_05), ""); + EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_eb_06), + NonTriviallyCopyableAggregate{}); +} + +// -------------------------------------------------------------------- + TEST_F(FlagTest, TestGetSet) { absl::SetFlag(&FLAGS_test_flag_01, false); EXPECT_EQ(absl::GetFlag(FLAGS_test_flag_01), false); diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index 344e31f6..0ef0ee74 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -647,7 +647,7 @@ T* MakeFromDefaultValue(T t) { template T* MakeFromDefaultValue(EmptyBraces) { - return new T; + return new T{}; } } // namespace flags_internal diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc index 415b239b..4f64f799 100644 --- a/absl/strings/cord.cc +++ b/absl/strings/cord.cc @@ -30,6 +30,7 @@ #include "absl/base/internal/raw_logging.h" #include "absl/base/port.h" #include "absl/container/fixed_array.h" +#include "absl/container/inlined_vector.h" #include "absl/strings/escaping.h" #include "absl/strings/internal/cord_internal.h" #include "absl/strings/internal/resize_uninitialized.h" @@ -131,14 +132,6 @@ inline const CordRepExternal* CordRep::external() const { return static_cast(this); } -using CordTreeConstPath = CordTreePath; - -// This type is used to store the list of pending nodes during re-balancing. -// Its maximum size is 2 * MaxCordDepth() because the tree has a maximum -// possible depth of MaxCordDepth() and every concat node along a tree path -// could theoretically be split during rebalancing. -using RebalancingStack = CordTreePath; - } // namespace cord_internal static const size_t kFlatOverhead = offsetof(CordRep, data); @@ -187,78 +180,98 @@ static constexpr size_t TagToLength(uint8_t tag) { // Enforce that kMaxFlatSize maps to a well-known exact tag value. static_assert(TagToAllocatedSize(224) == kMaxFlatSize, "Bad tag logic"); -constexpr size_t Fibonacci(uint8_t n, const size_t a = 0, const size_t b = 1) { - return n == 0 - ? a - : n == 1 ? b - : Fibonacci(n - 1, b, - (a > (size_t(-1) - b)) ? size_t(-1) : a + b); +constexpr uint64_t Fibonacci(unsigned char n, uint64_t a = 0, uint64_t b = 1) { + return n == 0 ? a : Fibonacci(n - 1, b, a + b); } +static_assert(Fibonacci(63) == 6557470319842, + "Fibonacci values computed incorrectly"); + // Minimum length required for a given depth tree -- a tree is considered // balanced if -// length(t) >= kMinLength[depth(t)] -// The node depth is allowed to become larger to reduce rebalancing -// for larger strings (see ShouldRebalance). -constexpr size_t kMinLength[] = { - Fibonacci(2), Fibonacci(3), Fibonacci(4), Fibonacci(5), Fibonacci(6), - Fibonacci(7), Fibonacci(8), Fibonacci(9), Fibonacci(10), Fibonacci(11), - Fibonacci(12), Fibonacci(13), Fibonacci(14), Fibonacci(15), Fibonacci(16), - Fibonacci(17), Fibonacci(18), Fibonacci(19), Fibonacci(20), Fibonacci(21), - Fibonacci(22), Fibonacci(23), Fibonacci(24), Fibonacci(25), Fibonacci(26), - Fibonacci(27), Fibonacci(28), Fibonacci(29), Fibonacci(30), Fibonacci(31), - Fibonacci(32), Fibonacci(33), Fibonacci(34), Fibonacci(35), Fibonacci(36), - Fibonacci(37), Fibonacci(38), Fibonacci(39), Fibonacci(40), Fibonacci(41), - Fibonacci(42), Fibonacci(43), Fibonacci(44), Fibonacci(45), Fibonacci(46), - Fibonacci(47), Fibonacci(48), Fibonacci(49), Fibonacci(50), Fibonacci(51), - Fibonacci(52), Fibonacci(53), Fibonacci(54), Fibonacci(55), Fibonacci(56), - Fibonacci(57), Fibonacci(58), Fibonacci(59), Fibonacci(60), Fibonacci(61), - Fibonacci(62), Fibonacci(63), Fibonacci(64), Fibonacci(65), Fibonacci(66), - Fibonacci(67), Fibonacci(68), Fibonacci(69), Fibonacci(70), Fibonacci(71), - Fibonacci(72), Fibonacci(73), Fibonacci(74), Fibonacci(75), Fibonacci(76), - Fibonacci(77), Fibonacci(78), Fibonacci(79), Fibonacci(80), Fibonacci(81), - Fibonacci(82), Fibonacci(83), Fibonacci(84), Fibonacci(85), Fibonacci(86), - Fibonacci(87), Fibonacci(88), Fibonacci(89), Fibonacci(90), Fibonacci(91), - Fibonacci(92), Fibonacci(93), Fibonacci(94), Fibonacci(95)}; - -static_assert(sizeof(kMinLength) / sizeof(size_t) >= - (cord_internal::MaxCordDepth() + 1), - "Not enough elements in kMinLength array to cover all the " - "supported Cord depth(s)"); - -inline bool ShouldRebalance(const CordRep* node) { - if (node->tag != CONCAT) return false; - - size_t node_depth = node->concat()->depth(); - - if (node_depth <= 15) return false; - - // Rebalancing Cords is expensive, so we reduce how often rebalancing occurs - // by allowing shallow Cords to have twice the depth that the Fibonacci rule - // would otherwise imply. Deep Cords need to follow the rule more closely, - // however to ensure algorithm correctness. We implement this with linear - // interpolation. Cords of depth 16 are treated as though they have a depth - // of 16 * 1/2, and Cords of depth MaxCordDepth() interpolate to - // MaxCordDepth() * 1. - return node->length < - kMinLength[(node_depth * (cord_internal::MaxCordDepth() - 16)) / - (2 * cord_internal::MaxCordDepth() - 16 - node_depth)]; -} - -// Unlike root balancing condition this one is part of the re-balancing -// algorithm and has to be always matching against right depth for -// algorithm to be correct. -inline bool IsNodeBalanced(const CordRep* node) { - if (node->tag != CONCAT) return true; - - size_t node_depth = node->concat()->depth(); - - return node->length >= kMinLength[node_depth]; +// length(t) >= min_length[depth(t)] +// The root node depth is allowed to become twice as large to reduce rebalancing +// for larger strings (see IsRootBalanced). +static constexpr uint64_t min_length[] = { + Fibonacci(2), + Fibonacci(3), + Fibonacci(4), + Fibonacci(5), + Fibonacci(6), + Fibonacci(7), + Fibonacci(8), + Fibonacci(9), + Fibonacci(10), + Fibonacci(11), + Fibonacci(12), + Fibonacci(13), + Fibonacci(14), + Fibonacci(15), + Fibonacci(16), + Fibonacci(17), + Fibonacci(18), + Fibonacci(19), + Fibonacci(20), + Fibonacci(21), + Fibonacci(22), + Fibonacci(23), + Fibonacci(24), + Fibonacci(25), + Fibonacci(26), + Fibonacci(27), + Fibonacci(28), + Fibonacci(29), + Fibonacci(30), + Fibonacci(31), + Fibonacci(32), + Fibonacci(33), + Fibonacci(34), + Fibonacci(35), + Fibonacci(36), + Fibonacci(37), + Fibonacci(38), + Fibonacci(39), + Fibonacci(40), + Fibonacci(41), + Fibonacci(42), + Fibonacci(43), + Fibonacci(44), + Fibonacci(45), + Fibonacci(46), + Fibonacci(47), + 0xffffffffffffffffull, // Avoid overflow +}; + +static const int kMinLengthSize = ABSL_ARRAYSIZE(min_length); + +// The inlined size to use with absl::InlinedVector. +// +// Note: The InlinedVectors in this file (and in cord.h) do not need to use +// the same value for their inlined size. The fact that they do is historical. +// It may be desirable for each to use a different inlined size optimized for +// that InlinedVector's usage. +// +// TODO(jgm): Benchmark to see if there's a more optimal value than 47 for +// the inlined vector size (47 exists for backward compatibility). +static const int kInlinedVectorSize = 47; + +static inline bool IsRootBalanced(CordRep* node) { + if (node->tag != CONCAT) { + return true; + } else if (node->concat()->depth() <= 15) { + return true; + } else if (node->concat()->depth() > kMinLengthSize) { + return false; + } else { + // Allow depth to become twice as large as implied by fibonacci rule to + // reduce rebalancing for larger strings. + return (node->length >= min_length[node->concat()->depth() / 2]); + } } static CordRep* Rebalance(CordRep* node); -static void DumpNode(const CordRep* rep, bool include_data, std::ostream* os); -static bool VerifyNode(const CordRep* root, const CordRep* start_node, +static void DumpNode(CordRep* rep, bool include_data, std::ostream* os); +static bool VerifyNode(CordRep* root, CordRep* start_node, bool full_validation); static inline CordRep* VerifyTree(CordRep* node) { @@ -305,8 +318,7 @@ __attribute__((preserve_most)) static void UnrefInternal(CordRep* rep) { assert(rep != nullptr); - cord_internal::RebalancingStack pending; - + absl::InlinedVector pending; while (true) { if (rep->tag == CONCAT) { CordRepConcat* rep_concat = rep->concat(); @@ -388,11 +400,6 @@ static void SetConcatChildren(CordRepConcat* concat, CordRep* left, concat->length = left->length + right->length; concat->set_depth(1 + std::max(Depth(left), Depth(right))); - - ABSL_INTERNAL_CHECK(concat->depth() <= cord_internal::MaxCordDepth(), - "Cord depth exceeds max"); - ABSL_INTERNAL_CHECK(concat->length >= left->length, "Cord is too long"); - ABSL_INTERNAL_CHECK(concat->length >= right->length, "Cord is too long"); } // Create a concatenation of the specified nodes. @@ -418,7 +425,7 @@ static CordRep* RawConcat(CordRep* left, CordRep* right) { static CordRep* Concat(CordRep* left, CordRep* right) { CordRep* rep = RawConcat(left, right); - if (rep != nullptr && ShouldRebalance(rep)) { + if (rep != nullptr && !IsRootBalanced(rep)) { rep = Rebalance(rep); } return VerifyTree(rep); @@ -909,7 +916,7 @@ void Cord::Prepend(absl::string_view src) { static CordRep* RemovePrefixFrom(CordRep* node, size_t n) { if (n >= node->length) return nullptr; if (n == 0) return Ref(node); - cord_internal::CordTreeMutablePath rhs_stack; + absl::InlinedVector rhs_stack; while (node->tag == CONCAT) { assert(n <= node->length); @@ -950,7 +957,7 @@ static CordRep* RemovePrefixFrom(CordRep* node, size_t n) { static CordRep* RemoveSuffixFrom(CordRep* node, size_t n) { if (n >= node->length) return nullptr; if (n == 0) return Ref(node); - absl::cord_internal::CordTreeMutablePath lhs_stack; + absl::InlinedVector lhs_stack; bool inplace_ok = node->refcount.IsOne(); while (node->tag == CONCAT) { @@ -1021,7 +1028,6 @@ void Cord::RemoveSuffix(size_t n) { // Work item for NewSubRange(). struct SubRange { - SubRange() = default; SubRange(CordRep* a_node, size_t a_pos, size_t a_n) : node(a_node), pos(a_pos), n(a_n) {} CordRep* node; // nullptr means concat last 2 results. @@ -1030,11 +1036,8 @@ struct SubRange { }; static CordRep* NewSubRange(CordRep* node, size_t pos, size_t n) { - cord_internal::CordTreeMutablePath results; - // The algorithm below in worst case scenario adds up to 3 nodes to the `todo` - // list, but we also pop one out on every cycle. If original tree has depth d - // todo list can grew up to 2*d in size. - cord_internal::CordTreePath todo; + absl::InlinedVector results; + absl::InlinedVector todo; todo.push_back(SubRange(node, pos, n)); do { const SubRange& sr = todo.back(); @@ -1071,7 +1074,7 @@ static CordRep* NewSubRange(CordRep* node, size_t pos, size_t n) { } } while (!todo.empty()); assert(results.size() == 1); - return results.back(); + return results[0]; } Cord Cord::Subcord(size_t pos, size_t new_size) const { @@ -1110,12 +1113,11 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const { class CordForest { public: - explicit CordForest(size_t length) : root_length_(length), trees_({}) {} + explicit CordForest(size_t length) + : root_length_(length), trees_(kMinLengthSize, nullptr) {} void Build(CordRep* cord_root) { - // We are adding up to two nodes to the `pending` list, but we also popping - // one, so the size of `pending` will never exceed `MaxCordDepth()`. - cord_internal::CordTreeMutablePath pending(cord_root); + std::vector pending = {cord_root}; while (!pending.empty()) { CordRep* node = pending.back(); @@ -1127,20 +1129,21 @@ class CordForest { } CordRepConcat* concat_node = node->concat(); - if (IsNodeBalanced(concat_node)) { - AddNode(node); - continue; - } - pending.push_back(concat_node->right); - pending.push_back(concat_node->left); - - if (concat_node->refcount.IsOne()) { - concat_node->left = concat_freelist_; - concat_freelist_ = concat_node; + if (concat_node->depth() >= kMinLengthSize || + concat_node->length < min_length[concat_node->depth()]) { + pending.push_back(concat_node->right); + pending.push_back(concat_node->left); + + if (concat_node->refcount.IsOne()) { + concat_node->left = concat_freelist_; + concat_freelist_ = concat_node; + } else { + Ref(concat_node->right); + Ref(concat_node->left); + Unref(concat_node); + } } else { - Ref(concat_node->right); - Ref(concat_node->left); - Unref(concat_node); + AddNode(node); } } } @@ -1172,7 +1175,7 @@ class CordForest { // Collect together everything with which we will merge with node int i = 0; - for (; node->length >= kMinLength[i + 1]; ++i) { + for (; node->length > min_length[i + 1]; ++i) { auto& tree_at_i = trees_[i]; if (tree_at_i == nullptr) continue; @@ -1183,7 +1186,7 @@ class CordForest { sum = AppendNode(node, sum); // Insert sum into appropriate place in the forest - for (; sum->length >= kMinLength[i]; ++i) { + for (; sum->length >= min_length[i]; ++i) { auto& tree_at_i = trees_[i]; if (tree_at_i == nullptr) continue; @@ -1191,7 +1194,7 @@ class CordForest { tree_at_i = nullptr; } - // kMinLength[0] == 1, which means sum->length >= kMinLength[0] + // min_length[0] == 1, which means sum->length >= min_length[0] assert(i > 0); trees_[i - 1] = sum; } @@ -1224,7 +1227,9 @@ class CordForest { } size_t root_length_; - std::array trees_; + + // use an inlined vector instead of a flat array to get bounds checking + absl::InlinedVector trees_; // List of concat nodes we can re-use for Cord balancing. CordRepConcat* concat_freelist_ = nullptr; @@ -1836,18 +1841,18 @@ absl::string_view Cord::FlattenSlowPath() { } } -static void DumpNode(const CordRep* rep, bool include_data, std::ostream* os) { +static void DumpNode(CordRep* rep, bool include_data, std::ostream* os) { const int kIndentStep = 1; int indent = 0; - cord_internal::CordTreeConstPath stack; - cord_internal::CordTreePath indents; + absl::InlinedVector stack; + absl::InlinedVector indents; for (;;) { *os << std::setw(3) << rep->refcount.Get(); *os << " " << std::setw(7) << rep->length; *os << " ["; - if (include_data) *os << static_cast(rep); + if (include_data) *os << static_cast(rep); *os << "]"; - *os << " " << (IsNodeBalanced(rep) ? 'b' : 'u'); + *os << " " << (IsRootBalanced(rep) ? 'b' : 'u'); *os << " " << std::setw(indent) << ""; if (rep->tag == CONCAT) { *os << "CONCAT depth=" << Depth(rep) << "\n"; @@ -1868,7 +1873,7 @@ static void DumpNode(const CordRep* rep, bool include_data, std::ostream* os) { } else { *os << "FLAT cap=" << TagToLength(rep->tag) << " ["; if (include_data) - *os << absl::CEscape(absl::string_view(rep->data, rep->length)); + *os << absl::CEscape(std::string(rep->data, rep->length)); *os << "]\n"; } if (stack.empty()) break; @@ -1881,19 +1886,19 @@ static void DumpNode(const CordRep* rep, bool include_data, std::ostream* os) { ABSL_INTERNAL_CHECK(indents.empty(), ""); } -static std::string ReportError(const CordRep* root, const CordRep* node) { +static std::string ReportError(CordRep* root, CordRep* node) { std::ostringstream buf; buf << "Error at node " << node << " in:"; DumpNode(root, true, &buf); return buf.str(); } -static bool VerifyNode(const CordRep* root, const CordRep* start_node, +static bool VerifyNode(CordRep* root, CordRep* start_node, bool full_validation) { - cord_internal::CordTreeConstPath worklist; + absl::InlinedVector worklist; worklist.push_back(start_node); do { - const CordRep* node = worklist.back(); + CordRep* node = worklist.back(); worklist.pop_back(); ABSL_INTERNAL_CHECK(node != nullptr, ReportError(root, node)); @@ -1943,7 +1948,7 @@ static bool VerifyNode(const CordRep* root, const CordRep* start_node, // Iterate over the tree. cur_node is never a leaf node and leaf nodes will // never be appended to tree_stack. This reduces overhead from manipulating // tree_stack. - cord_internal::CordTreeConstPath tree_stack; + absl::InlinedVector tree_stack; const CordRep* cur_node = rep; while (true) { const CordRep* next_node = nullptr; diff --git a/absl/strings/cord.h b/absl/strings/cord.h index eb236e50..66645eef 100644 --- a/absl/strings/cord.h +++ b/absl/strings/cord.h @@ -48,6 +48,7 @@ #include "absl/base/internal/per_thread_tls.h" #include "absl/base/macros.h" #include "absl/base/port.h" +#include "absl/container/inlined_vector.h" #include "absl/functional/function_ref.h" #include "absl/meta/type_traits.h" #include "absl/strings/internal/cord_internal.h" @@ -67,55 +68,6 @@ template H HashFragmentedCord(H, const Cord&); } -namespace cord_internal { - -// It's expensive to keep a tree perfectly balanced, so instead we keep trees -// approximately balanced. A tree node N of depth D(N) that contains a string -// of L(N) characters is considered balanced if L >= Fibonacci(D + 2). -// The "+ 2" is used to ensure that every balanced leaf node contains at least -// one character. Here we presume that -// Fibonacci(0) = 0 -// Fibonacci(1) = 1 -// Fibonacci(2) = 1 -// Fibonacci(3) = 2 -// ... -// The algorithm is based on paper by Hans Boehm et al: -// https://www.cs.rit.edu/usr/local/pub/jeh/courses/QUARTERS/FP/Labs/CedarRope/rope-paper.pdf -// In this paper authors shows that rebalancing based on cord forest of already -// balanced subtrees can be proven to never produce tree of depth larger than -// largest Fibonacci number representable in the same integral type as cord size -// For 64 bit integers this is the 93rd Fibonacci number. For 32 bit integrals -// this is 47th Fibonacci number. -constexpr size_t MaxCordDepth() { return sizeof(size_t) == 8 ? 93 : 47; } - -// This class models fixed max size stack of CordRep pointers. -// The elements are being pushed back and popped from the back. -template -class CordTreePath { - public: - CordTreePath() {} - explicit CordTreePath(CordRepPtr root) { push_back(root); } - - bool empty() const { return size_ == 0; } - size_t size() const { return size_; } - void clear() { size_ = 0; } - - CordRepPtr back() { return data_[size_ - 1]; } - - void pop_back() { - --size_; - assert(size_ < N); - } - void push_back(CordRepPtr elem) { data_[size_++] = elem; } - - private: - CordRepPtr data_[N]; - size_t size_ = 0; -}; - -using CordTreeMutablePath = CordTreePath; -} // namespace cord_internal - // A Cord is a sequence of characters. class Cord { private: @@ -333,7 +285,8 @@ class Cord { absl::cord_internal::CordRep* current_leaf_ = nullptr; // The number of bytes left in the `Cord` over which we are iterating. size_t bytes_remaining_ = 0; - absl::cord_internal::CordTreeMutablePath stack_of_right_children_; + absl::InlinedVector + stack_of_right_children_; }; // Returns an iterator to the first chunk of the `Cord`. diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc index f2d81d4c..4afa4a26 100644 --- a/absl/strings/cord_test.cc +++ b/absl/strings/cord_test.cc @@ -1402,53 +1402,6 @@ TEST(CordChunkIterator, Operations) { VerifyChunkIterator(subcords, 128); } -TEST(CordChunkIterator, MaxLengthFullTree) { - // Start with a 1-byte cord, and then double its length in a loop. We should - // be able to do this until the point where we would overflow size_t. - - absl::Cord cord; - size_t size = 1; - AddExternalMemory("x", &cord); - EXPECT_EQ(cord.size(), size); - - const int kCordLengthDoublingLimit = std::numeric_limits::digits - 1; - for (int i = 0; i < kCordLengthDoublingLimit; ++i) { - cord.Prepend(absl::Cord(cord)); - size <<= 1; - - EXPECT_EQ(cord.size(), size); - - auto chunk_it = cord.chunk_begin(); - EXPECT_EQ(*chunk_it, "x"); - } - - EXPECT_DEATH_IF_SUPPORTED( - (cord.Prepend(absl::Cord(cord)), *cord.chunk_begin()), - "Cord is too long"); -} - -TEST(CordChunkIterator, MaxDepth) { - // By reusing nodes, it's possible in pathological cases to build a Cord that - // exceeds both the maximum permissible length and depth. In this case, the - // violation of the maximum depth is reported. - absl::Cord left_child; - AddExternalMemory("x", &left_child); - absl::Cord root = left_child; - - for (int i = 0; i < absl::cord_internal::MaxCordDepth() - 2; ++i) { - size_t new_size = left_child.size() + root.size(); - root.Prepend(left_child); - EXPECT_EQ(root.size(), new_size); - - auto chunk_it = root.chunk_begin(); - EXPECT_EQ(*chunk_it, "x"); - - std::swap(left_child, root); - } - - EXPECT_DEATH_IF_SUPPORTED(root.Prepend(left_child), "Cord is too long"); -} - TEST(CordCharIterator, Traits) { static_assert(std::is_copy_constructible::value, ""); diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index d1665753..968850eb 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h @@ -24,6 +24,7 @@ #include "absl/base/config.h" #include "absl/base/port.h" +#include "absl/meta/type_traits.h" #include "absl/strings/internal/str_format/output.h" #include "absl/strings/string_view.h" @@ -365,11 +366,22 @@ constexpr FormatConversionCharSet operator|(FormatConversionCharSet a, static_cast(b)); } +// Overloaded conversion functions to support absl::ParsedFormat. // Get a conversion with a single character in it. -constexpr FormatConversionCharSet ConversionCharToConv(char c) { - return FormatConversionCharSet(FormatConversionCharToConvValue(c)); +constexpr FormatConversionCharSet ToFormatConversionCharSet(char c) { + return static_cast( + FormatConversionCharToConvValue(c)); } +// Get a conversion with a single character in it. +constexpr FormatConversionCharSet ToFormatConversionCharSet( + FormatConversionCharSet c) { + return c; +} + +template +void ToFormatConversionCharSet(T) = delete; + // Checks whether `c` exists in `set`. constexpr bool Contains(FormatConversionCharSet set, char c) { return (static_cast(set) & FormatConversionCharToConvValue(c)) != 0; diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index 2f9b4b27..d40fca11 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -285,7 +285,7 @@ using FormatSpec = // } template using ParsedFormat = str_format_internal::ExtendedParsedFormat< - str_format_internal::ConversionCharToConv(Conv)...>; + absl::str_format_internal::ToFormatConversionCharSet(Conv)...>; // StrFormat() // diff --git a/ci/macos_xcode_cmake.sh b/ci/macos_xcode_cmake.sh index aa9ee15d..a1f4a857 100755 --- a/ci/macos_xcode_cmake.sh +++ b/ci/macos_xcode_cmake.sh @@ -36,7 +36,7 @@ for compilation_mode in ${ABSL_CMAKE_BUILD_TYPES}; do time cmake ${ABSEIL_ROOT} \ -GXcode \ -DCMAKE_BUILD_TYPE=${compilation_mode} \ - -DCMAKE_CXX_FLAGS=-std=c++14 \ + -DCMAKE_CXX_STANDARD=11 \ -DABSL_USE_GOOGLETEST_HEAD=ON \ -DABSL_RUN_TESTS=ON time cmake --build . -- cgit v1.2.3 From 672d9e0aef6e856c1258d0810143d1f202d3204d Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 16 Jul 2020 18:14:20 -0700 Subject: Export of internal Abseil changes -- d2b7a83bafb90d35b2b7d8eb4177e9d712e8d62c by Gennadiy Rozental : Introduce ABSL specific macros for detecting the usage of sanitizers. PiperOrigin-RevId: 321687443 -- a41342cc04b1088087dda12d7272aa3835f8e36a by Evan Brown : Get rid of recursion in clear_and_delete(). PiperOrigin-RevId: 321583786 -- 99c6d300b17f186c28867b08cc79f1e55077e88a by Evan Brown : Code simplification: consolidate methods to erase values/nodes. Motivation: this will make floating storage work simpler. - Delete erase_same_node/erase_from_leaf_node/remove_value/remove_values_ignore_children. - Move node deletion methods inside btree_node. - Delete three-argument move() and use transfer_n() instead. - Note: there's still one usage of move (in btree::erase(iterator)) that could use transfer, but I think doing so would add more complexity than it's worth. PiperOrigin-RevId: 321407673 -- c3efed6c1763190c6b3bccbede9b2989ab21b258 by Evan Brown : Support heterogeneous insert_or_assign, try_emplace, operator[] for btree_map. Also do a bit of cleanup: - Add _impl methods for insert_or_assign/try_emplace. - Rename some hint iterator params from `position` to `hint`. PiperOrigin-RevId: 321399557 GitOrigin-RevId: d2b7a83bafb90d35b2b7d8eb4177e9d712e8d62c Change-Id: Ie2d0c7c3ed197c2b53d475248941392cbad20e59 --- absl/base/config.h | 66 +++++++- absl/base/dynamic_annotations.h | 57 +++---- absl/container/btree_test.cc | 33 ++++ absl/container/internal/btree.h | 244 ++++++++++++----------------- absl/container/internal/btree_container.h | 199 ++++++++++++----------- absl/container/internal/container_memory.h | 7 - 6 files changed, 312 insertions(+), 294 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index f54466de..b1e095d3 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -154,6 +154,12 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_INTERNAL_HAS_KEYWORD(x) 0 #endif +#ifdef __has_feature +#define ABSL_HAVE_FEATURE(f) __has_feature(f) +#else +#define ABSL_HAVE_FEATURE(f) 0 +#endif + // ABSL_HAVE_TLS is defined to 1 when __thread should be supported. // We assume __thread is supported on Linux when compiled with Clang or compiled // against libstdc++ with _GLIBCXX_HAVE_TLS defined. @@ -226,11 +232,9 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || // * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator // targeting iOS 9.x. // * Xcode 10 moves the deployment target check for iOS < 9.0 to link time -// making __has_feature unreliable there. +// making ABSL_HAVE_FEATURE unreliable there. // -// Otherwise, `__has_feature` is only supported by Clang so it has be inside -// `defined(__APPLE__)` check. -#if __has_feature(cxx_thread_local) && \ +#if ABSL_HAVE_FEATURE(cxx_thread_local) && \ !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0) #define ABSL_HAVE_THREAD_LOCAL 1 #endif @@ -312,15 +316,15 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6) // Clang >= 3.6 -#if __has_feature(cxx_exceptions) +#if ABSL_HAVE_FEATURE(cxx_exceptions) #define ABSL_HAVE_EXCEPTIONS 1 -#endif // __has_feature(cxx_exceptions) +#endif // ABSL_HAVE_FEATURE(cxx_exceptions) #else // Clang < 3.6 // http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro -#if defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) +#if defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) #define ABSL_HAVE_EXCEPTIONS 1 -#endif // defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) +#endif // defined(__EXCEPTIONS) && ABSL_HAVE_FEATURE(cxx_exceptions) #endif // __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6) // Handle remaining special cases and default to exceptions being supported. @@ -661,4 +665,50 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_DLL #endif // defined(_MSC_VER) +// ABSL_HAVE_MEMORY_SANITIZER +// +// MemorySanitizer (MSan) is a detector of uninitialized reads. It consists of +// a compiler instrumentation module and a run-time library. +#ifdef ABSL_HAVE_MEMORY_SANITIZER +#error "ABSL_HAVE_MEMORY_SANITIZER cannot be directly set." +#elif defined(MEMORY_SANITIZER) +// The MEMORY_SANITIZER macro is deprecated but we will continue to honor it +// for now. +#define ABSL_HAVE_MEMORY_SANITIZER 1 +#elif defined(__SANITIZE_MEMORY__) +#define ABSL_HAVE_MEMORY_SANITIZER 1 +#elif !defined(__native_client__) && ABSL_HAVE_FEATURE(memory_sanitizer) +#define ABSL_HAVE_MEMORY_SANITIZER 1 +#endif + +// ABSL_HAVE_THREAD_SANITIZER +// +// ThreadSanitizer (TSan) is a fast data race detector. +#ifdef ABSL_HAVE_THREAD_SANITIZER +#error "ABSL_HAVE_THREAD_SANITIZER cannot be directly set." +#elif defined(THREAD_SANITIZER) +// The THREAD_SANITIZER macro is deprecated but we will continue to honor it +// for now. +#define ABSL_HAVE_THREAD_SANITIZER 1 +#elif defined(__SANITIZE_THREAD__) +#define ABSL_HAVE_THREAD_SANITIZER 1 +#elif ABSL_HAVE_FEATURE(thread_sanitizer) +#define ABSL_HAVE_THREAD_SANITIZER 1 +#endif + +// ABSL_HAVE_ADDRESS_SANITIZER +// +// AddressSanitizer (ASan) is a fast memory error detector. +#ifdef ABSL_HAVE_ADDRESS_SANITIZER +#error "ABSL_HAVE_ADDRESS_SANITIZER cannot be directly set." +#elif defined(ADDRESS_SANITIZER) +// The ADDRESS_SANITIZER macro is deprecated but we will continue to honor it +// for now. +#define ABSL_HAVE_ADDRESS_SANITIZER 1 +#elif defined(__SANITIZE_ADDRESS__) +#define ABSL_HAVE_ADDRESS_SANITIZER 1 +#elif ABSL_HAVE_FEATURE(address_sanitizer) +#define ABSL_HAVE_ADDRESS_SANITIZER 1 +#endif + #endif // ABSL_BASE_CONFIG_H_ diff --git a/absl/base/dynamic_annotations.h b/absl/base/dynamic_annotations.h index 1444dc48..5ea697b7 100644 --- a/absl/base/dynamic_annotations.h +++ b/absl/base/dynamic_annotations.h @@ -53,19 +53,9 @@ #include "absl/base/internal/dynamic_annotations.h" // IWYU pragma: export // ------------------------------------------------------------------------- -// Decide which features are enabled +// Decide which features are enabled. -#ifndef DYNAMIC_ANNOTATIONS_ENABLED -#define DYNAMIC_ANNOTATIONS_ENABLED 0 -#endif - -#if defined(__clang__) && !defined(SWIG) -#define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 1 -#else -#define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 0 -#endif - -#if DYNAMIC_ANNOTATIONS_ENABLED != 0 +#ifdef ABSL_HAVE_THREAD_SANITIZER #define ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED 1 #define ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED 1 @@ -85,24 +75,21 @@ // will issue a warning, if these attributes are compiled. Only include them // when compiling using Clang. -// ANNOTALYSIS_ENABLED == 1 when IGNORE_READ_ATTRIBUTE_ENABLED == 1 -#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED \ - ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED -// Read/write annotations are enabled in Annotalysis mode; disabled otherwise. -#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED \ - ABSL_INTERNAL_ANNOTALYSIS_ENABLED -#endif - -// Memory annotations are also made available to LLVM's Memory Sanitizer -#if defined(MEMORY_SANITIZER) && defined(__has_feature) && \ - !defined(__native_client__) -#if __has_feature(memory_sanitizer) -#define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 1 +#if defined(__clang__) +#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 1 +#if !defined(SWIG) +#define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 1 +#else +#define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 0 #endif +#else +#define ABSL_INTERNAL_ANNOTALYSIS_ENABLED 0 +#define ABSL_INTERNAL_IGNORE_READS_ATTRIBUTE_ENABLED 0 #endif -#ifndef ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED -#define ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED 0 +// Read/write annotations are enabled in Annotalysis mode; disabled otherwise. +#define ABSL_INTERNAL_READS_WRITES_ANNOTATIONS_ENABLED \ + ABSL_INTERNAL_ANNOTALYSIS_ENABLED #endif #ifdef __cplusplus @@ -243,7 +230,7 @@ ABSL_INTERNAL_END_EXTERN_C // ------------------------------------------------------------------------- // Define memory annotations. -#if ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED == 1 +#ifdef ABSL_HAVE_MEMORY_SANITIZER #include @@ -253,9 +240,10 @@ ABSL_INTERNAL_END_EXTERN_C #define ABSL_ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ __msan_allocated_memory(address, size) -#else // ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED == 0 +#else // !defined(ABSL_HAVE_MEMORY_SANITIZER) -#if DYNAMIC_ANNOTATIONS_ENABLED == 1 +// TODO(rogeeff): remove this branch +#ifdef ABSL_HAVE_THREAD_SANITIZER #define ABSL_ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ do { \ (void)(address); \ @@ -273,7 +261,7 @@ ABSL_INTERNAL_END_EXTERN_C #endif -#endif // ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED +#endif // ABSL_HAVE_MEMORY_SANITIZER // ------------------------------------------------------------------------- // Define IGNORE_READS_BEGIN/_END attributes. @@ -468,7 +456,7 @@ ABSL_INTERNAL_END_EXTERN_C // ------------------------------------------------------------------------- // Address sanitizer annotations -#ifdef ADDRESS_SANITIZER +#ifdef ABSL_HAVE_ADDRESS_SANITIZER // Describe the current state of a contiguous container such as e.g. // std::vector or std::string. For more details see // sanitizer/common_interface_defs.h, which is provided by the compiler. @@ -483,16 +471,15 @@ ABSL_INTERNAL_END_EXTERN_C #else -#define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) +#define ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) // empty #define ABSL_ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "") -#endif // ADDRESS_SANITIZER +#endif // ABSL_HAVE_ADDRESS_SANITIZER // ------------------------------------------------------------------------- // Undefine the macros intended only for this file. #undef ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED -#undef ABSL_INTERNAL_MEMORY_ANNOTATIONS_ENABLED #undef ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED #undef ABSL_INTERNAL_WRITES_ANNOTATIONS_ENABLED #undef ABSL_INTERNAL_ANNOTALYSIS_ENABLED diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc index c5808074..67ee7521 100644 --- a/absl/container/btree_test.cc +++ b/absl/container/btree_test.cc @@ -2509,6 +2509,39 @@ TEST(Btree, EXPECT_THAT(m2, ElementsAre(Pair(IsEmpty(), 1), Pair(ElementsAre(IsNull()), 2))); } + +TEST(Btree, HeterogeneousTryEmplace) { + absl::btree_map m; + std::string s = "key"; + absl::string_view sv = s; + m.try_emplace(sv, 1); + EXPECT_EQ(m[s], 1); + + m.try_emplace(m.end(), sv, 2); + EXPECT_EQ(m[s], 1); +} + +TEST(Btree, HeterogeneousOperatorMapped) { + absl::btree_map m; + std::string s = "key"; + absl::string_view sv = s; + m[sv] = 1; + EXPECT_EQ(m[s], 1); + + m[sv] = 2; + EXPECT_EQ(m[s], 2); +} + +TEST(Btree, HeterogeneousInsertOrAssign) { + absl::btree_map m; + std::string s = "key"; + absl::string_view sv = s; + m.insert_or_assign(sv, 1); + EXPECT_EQ(m[s], 1); + + m.insert_or_assign(m.end(), sv, 2); + EXPECT_EQ(m[s], 2); +} #endif } // namespace diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h index 996afa61..188631d1 100644 --- a/absl/container/internal/btree.h +++ b/absl/container/internal/btree.h @@ -255,10 +255,6 @@ struct common_params { static void move(Alloc *alloc, slot_type *src, slot_type *dest) { slot_policy::move(alloc, src, dest); } - static void move(Alloc *alloc, slot_type *first, slot_type *last, - slot_type *result) { - slot_policy::move(alloc, first, last, result); - } }; // A parameters structure for holding the type parameters for a btree_map. @@ -336,13 +332,6 @@ struct set_slot_policy { static void move(Alloc * /*alloc*/, slot_type *src, slot_type *dest) { *dest = std::move(*src); } - - template - static void move(Alloc *alloc, slot_type *first, slot_type *last, - slot_type *result) { - for (slot_type *src = first, *dest = result; src != last; ++src, ++dest) - move(alloc, src, dest); - } }; // A parameters structure for holding the type parameters for a btree_set. @@ -759,14 +748,10 @@ class btree_node { template void emplace_value(size_type i, allocator_type *alloc, Args &&... args); - // Removes the value at position i, shifting all existing values and children - // at positions > i to the left by 1. - void remove_value(int i, allocator_type *alloc); - - // Removes the values at positions [i, i + to_erase), shifting all values - // after that range to the left by to_erase. Does not change children at all. - void remove_values_ignore_children(int i, int to_erase, - allocator_type *alloc); + // Removes the values at positions [i, i + to_erase), shifting all existing + // values and children after that range to the left by to_erase. Clears all + // children between [i, i + to_erase). + void remove_values(field_type i, field_type to_erase, allocator_type *alloc); // Rebalances a node with its right sibling. void rebalance_right_to_left(int to_move, btree_node *right, @@ -778,7 +763,7 @@ class btree_node { void split(int insert_position, btree_node *dest, allocator_type *alloc); // Merges a node with its right sibling, moving all of the values and the - // delimiting key in the parent node onto itself. + // delimiting key in the parent node onto itself, and deleting the src node. void merge(btree_node *src, allocator_type *alloc); // Node allocation/deletion routines. @@ -799,12 +784,15 @@ class btree_node { absl::container_internal::SanitizerPoisonMemoryRegion( &mutable_child(start()), (kNodeValues + 1) * sizeof(btree_node *)); } - void destroy(allocator_type *alloc) { - for (int i = start(); i < finish(); ++i) { - value_destroy(i, alloc); - } + + static void deallocate(const size_type size, btree_node *node, + allocator_type *alloc) { + absl::container_internal::Deallocate(alloc, node, size); } + // Deletes a node and all of its children. + static void clear_and_delete(btree_node *node, allocator_type *alloc); + public: // Exposed only for tests. static bool testonly_uses_linear_node_search() { @@ -813,14 +801,21 @@ class btree_node { private: template - void value_init(const size_type i, allocator_type *alloc, Args &&... args) { + void value_init(const field_type i, allocator_type *alloc, Args &&... args) { absl::container_internal::SanitizerUnpoisonObject(slot(i)); params_type::construct(alloc, slot(i), std::forward(args)...); } - void value_destroy(const size_type i, allocator_type *alloc) { + void value_destroy(const field_type i, allocator_type *alloc) { params_type::destroy(alloc, slot(i)); absl::container_internal::SanitizerPoisonObject(slot(i)); } + void value_destroy_n(const field_type i, const field_type n, + allocator_type *alloc) { + for (slot_type *s = slot(i), *end = slot(i + n); s != end; ++s) { + params_type::destroy(alloc, s); + absl::container_internal::SanitizerPoisonObject(s); + } + } // Transfers value from slot `src_i` in `src_node` to slot `dest_i` in `this`. void transfer(const size_type dest_i, const size_type src_i, @@ -1423,25 +1418,8 @@ class btree { } // Deletion helper routines. - void erase_same_node(iterator begin, iterator end); - iterator erase_from_leaf_node(iterator begin, size_type to_erase); iterator rebalance_after_delete(iterator iter); - // Deallocates a node of a certain size in bytes using the allocator. - void deallocate(const size_type size, node_type *node) { - absl::container_internal::Deallocate( - mutable_allocator(), node, size); - } - - void delete_internal_node(node_type *node) { - node->destroy(mutable_allocator()); - deallocate(node_type::InternalSize(), node); - } - void delete_leaf_node(node_type *node) { - node->destroy(mutable_allocator()); - deallocate(node_type::LeafSize(node->max_count()), node); - } - // Rebalances or splits the node iter points to. void rebalance_or_split(iterator *iter); @@ -1510,9 +1488,6 @@ class btree { template iterator internal_find(const K &key) const; - // Deletes a node and all of its children. - void internal_clear(node_type *node); - // Verifies the tree structure of node. int internal_verify(const node_type *node, const key_type *lo, const key_type *hi) const; @@ -1580,26 +1555,27 @@ inline void btree_node

::emplace_value(const size_type i, } template -inline void btree_node

::remove_value(const int i, allocator_type *alloc) { - if (!leaf() && finish() > i + 1) { - assert(child(i + 1)->count() == 0); - for (size_type j = i + 1; j < finish(); ++j) { - set_child(j, child(j + 1)); - } - clear_child(finish()); - } - - remove_values_ignore_children(i, /*to_erase=*/1, alloc); -} +inline void btree_node

::remove_values(const field_type i, + const field_type to_erase, + allocator_type *alloc) { + // Transfer values after the removed range into their new places. + value_destroy_n(i, to_erase, alloc); + const field_type orig_finish = finish(); + const field_type src_i = i + to_erase; + transfer_n(orig_finish - src_i, i, src_i, this, alloc); -template -inline void btree_node

::remove_values_ignore_children( - const int i, const int to_erase, allocator_type *alloc) { - params_type::move(alloc, slot(i + to_erase), finish_slot(), slot(i)); - for (int j = finish() - to_erase; j < finish(); ++j) { - value_destroy(j, alloc); + if (!leaf()) { + // Delete all children between begin and end. + for (field_type j = 0; j < to_erase; ++j) { + clear_and_delete(child(i + j + 1), alloc); + } + // Rotate children after end into new positions. + for (field_type j = i + to_erase + 1; j <= orig_finish; ++j) { + set_child(j - to_erase, child(j)); + clear_child(j); + } } - set_finish(finish() - to_erase); + set_finish(orig_finish - to_erase); } template @@ -1751,8 +1727,51 @@ void btree_node

::merge(btree_node *src, allocator_type *alloc) { set_finish(start() + 1 + count() + src->count()); src->set_finish(src->start()); - // Remove the value on the parent node. - parent()->remove_value(position(), alloc); + // Remove the value on the parent node and delete the src node. + parent()->remove_values(position(), /*to_erase=*/1, alloc); +} + +template +void btree_node

::clear_and_delete(btree_node *node, allocator_type *alloc) { + if (node->leaf()) { + node->value_destroy_n(node->start(), node->count(), alloc); + deallocate(LeafSize(node->max_count()), node, alloc); + return; + } + if (node->count() == 0) { + deallocate(InternalSize(), node, alloc); + return; + } + + // The parent of the root of the subtree we are deleting. + btree_node *delete_root_parent = node->parent(); + + // Navigate to the leftmost leaf under node, and then delete upwards. + while (!node->leaf()) node = node->start_child(); + field_type pos = node->position(); + btree_node *parent = node->parent(); + do { + // In each iteration of this loop, we delete one leaf node and go right. + for (; pos <= parent->finish(); ++pos) { + node = parent->child(pos); + if (!node->leaf()) { + // Navigate to the leftmost leaf under node. + while (!node->leaf()) node = node->start_child(); + pos = node->position(); + parent = node->parent(); + } + node->value_destroy_n(node->start(), node->count(), alloc); + deallocate(LeafSize(node->max_count()), node, alloc); + } + // If we've deleted all children of parent, then delete parent and go up. + for (; parent != delete_root_parent && pos > parent->finish(); ++pos) { + node = parent; + pos = node->position(); + parent = node->parent(); + node->value_destroy_n(node->start(), node->count(), alloc); + deallocate(InternalSize(), node, alloc); + } + } while (parent != delete_root_parent); } //// @@ -2034,7 +2053,7 @@ auto btree

::erase(iterator iter) -> iterator { bool internal_delete = false; if (!iter.node->leaf()) { // Deletion of a value on an internal node. First, move the largest value - // from our left child here, then delete that position (in remove_value() + // from our left child here, then delete that position (in remove_values() // below). We can get to the largest value from our left child by // decrementing iter. iterator internal_iter(iter); @@ -2046,7 +2065,7 @@ auto btree

::erase(iterator iter) -> iterator { } // Delete the key from the leaf. - iter.node->remove_value(iter.position, mutable_allocator()); + iter.node->remove_values(iter.position, /*to_erase=*/1, mutable_allocator()); --size_; // We want to return the next value after the one we just erased. If we @@ -2121,7 +2140,9 @@ auto btree

::erase_range(iterator begin, iterator end) } if (begin.node == end.node) { - erase_same_node(begin, end); + assert(end.position > begin.position); + begin.node->remove_values(begin.position, end.position - begin.position, + mutable_allocator()); size_ -= count; return {count, rebalance_after_delete(begin)}; } @@ -2131,8 +2152,11 @@ auto btree

::erase_range(iterator begin, iterator end) if (begin.node->leaf()) { const size_type remaining_to_erase = size_ - target_size; const size_type remaining_in_node = begin.node->finish() - begin.position; - begin = erase_from_leaf_node( - begin, (std::min)(remaining_to_erase, remaining_in_node)); + const size_type to_erase = + (std::min)(remaining_to_erase, remaining_in_node); + begin.node->remove_values(begin.position, to_erase, mutable_allocator()); + size_ -= to_erase; + begin = rebalance_after_delete(begin); } else { begin = erase(begin); } @@ -2140,51 +2164,6 @@ auto btree

::erase_range(iterator begin, iterator end) return {count, begin}; } -template -void btree

::erase_same_node(iterator begin, iterator end) { - assert(begin.node == end.node); - assert(end.position > begin.position); - - node_type *node = begin.node; - size_type to_erase = end.position - begin.position; - if (!node->leaf()) { - // Delete all children between begin and end. - for (size_type i = 0; i < to_erase; ++i) { - internal_clear(node->child(begin.position + i + 1)); - } - // Rotate children after end into new positions. - for (size_type i = begin.position + to_erase + 1; i <= node->finish(); - ++i) { - node->set_child(i - to_erase, node->child(i)); - node->clear_child(i); - } - } - node->remove_values_ignore_children(begin.position, to_erase, - mutable_allocator()); - - // Do not need to update rightmost_, because - // * either end == this->end(), and therefore node == rightmost_, and still - // exists - // * or end != this->end(), and therefore rightmost_ hasn't been erased, since - // it wasn't covered in [begin, end) -} - -template -auto btree

::erase_from_leaf_node(iterator begin, size_type to_erase) - -> iterator { - node_type *node = begin.node; - assert(node->leaf()); - assert(node->finish() > begin.position); - assert(begin.position + to_erase <= node->finish()); - - node->remove_values_ignore_children(begin.position, to_erase, - mutable_allocator()); - - size_ -= to_erase; - - return rebalance_after_delete(begin); -} - template template auto btree

::erase_unique(const K &key) -> size_type { @@ -2213,7 +2192,7 @@ auto btree

::erase_multi(const K &key) -> size_type { template void btree

::clear() { if (!empty()) { - internal_clear(root()); + node_type::clear_and_delete(root(), mutable_allocator()); } mutable_root() = EmptyNode(); rightmost_ = EmptyNode(); @@ -2354,12 +2333,7 @@ void btree

::rebalance_or_split(iterator *iter) { template void btree

::merge_nodes(node_type *left, node_type *right) { left->merge(right, mutable_allocator()); - if (right->leaf()) { - if (rightmost_ == right) rightmost_ = left; - delete_leaf_node(right); - } else { - delete_internal_node(right); - } + if (rightmost_ == right) rightmost_ = left; } template @@ -2416,20 +2390,20 @@ bool btree

::try_merge_or_rebalance(iterator *iter) { template void btree

::try_shrink() { - if (root()->count() > 0) { + node_type *orig_root = root(); + if (orig_root->count() > 0) { return; } // Deleted the last item on the root node, shrink the height of the tree. - if (root()->leaf()) { + if (orig_root->leaf()) { assert(size() == 0); - delete_leaf_node(root()); mutable_root() = rightmost_ = EmptyNode(); } else { - node_type *child = root()->start_child(); + node_type *child = orig_root->start_child(); child->make_root(); - delete_internal_node(root()); mutable_root() = child; } + node_type::clear_and_delete(orig_root, mutable_allocator()); } template @@ -2474,7 +2448,7 @@ inline auto btree

::internal_emplace(iterator iter, Args &&... args) old_root->start(), old_root, alloc); new_root->set_finish(old_root->finish()); old_root->set_finish(old_root->start()); - delete_leaf_node(old_root); + node_type::clear_and_delete(old_root, alloc); mutable_root() = rightmost_ = new_root; } else { rebalance_or_split(&iter); @@ -2577,18 +2551,6 @@ auto btree

::internal_find(const K &key) const -> iterator { return {nullptr, 0}; } -template -void btree

::internal_clear(node_type *node) { - if (!node->leaf()) { - for (int i = node->start(); i <= node->finish(); ++i) { - internal_clear(node->child(i)); - } - delete_internal_node(node); - } else { - delete_leaf_node(node); - } -} - template int btree

::internal_verify(const node_type *node, const key_type *lo, const key_type *hi) const { diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h index d0fc6451..3b2e8a9e 100644 --- a/absl/container/internal/btree_container.h +++ b/absl/container/internal/btree_container.h @@ -268,23 +268,21 @@ class btree_set_container : public btree_container { init_type v(std::forward(args)...); return this->tree_.insert_unique(params_type::key(v), std::move(v)); } - iterator insert(const_iterator position, const value_type &v) { + iterator insert(const_iterator hint, const value_type &v) { return this->tree_ - .insert_hint_unique(iterator(position), params_type::key(v), v) + .insert_hint_unique(iterator(hint), params_type::key(v), v) .first; } - iterator insert(const_iterator position, value_type &&v) { + iterator insert(const_iterator hint, value_type &&v) { return this->tree_ - .insert_hint_unique(iterator(position), params_type::key(v), - std::move(v)) + .insert_hint_unique(iterator(hint), params_type::key(v), std::move(v)) .first; } template - iterator emplace_hint(const_iterator position, Args &&... args) { + iterator emplace_hint(const_iterator hint, Args &&... args) { init_type v(std::forward(args)...); return this->tree_ - .insert_hint_unique(iterator(position), params_type::key(v), - std::move(v)) + .insert_hint_unique(iterator(hint), params_type::key(v), std::move(v)) .first; } template @@ -392,111 +390,72 @@ class btree_map_container : public btree_set_container { // Insertion routines. // Note: the nullptr template arguments and extra `const M&` overloads allow // for supporting bitfield arguments. - // Note: when we call `std::forward(obj)` twice, it's safe because - // insert_unique/insert_hint_unique are guaranteed to not consume `obj` when - // `ret.second` is false. - template - std::pair insert_or_assign(const key_type &k, const M &obj) { - const std::pair ret = this->tree_.insert_unique(k, k, obj); - if (!ret.second) ret.first->second = obj; - return ret; + template + std::pair insert_or_assign(const key_arg &k, + const M &obj) { + return insert_or_assign_impl(k, obj); } - template - std::pair insert_or_assign(key_type &&k, const M &obj) { - const std::pair ret = - this->tree_.insert_unique(k, std::move(k), obj); - if (!ret.second) ret.first->second = obj; - return ret; + template + std::pair insert_or_assign(key_arg &&k, const M &obj) { + return insert_or_assign_impl(std::forward(k), obj); } - template - std::pair insert_or_assign(const key_type &k, M &&obj) { - const std::pair ret = - this->tree_.insert_unique(k, k, std::forward(obj)); - if (!ret.second) ret.first->second = std::forward(obj); - return ret; + template + std::pair insert_or_assign(const key_arg &k, M &&obj) { + return insert_or_assign_impl(k, std::forward(obj)); } - template - std::pair insert_or_assign(key_type &&k, M &&obj) { - const std::pair ret = - this->tree_.insert_unique(k, std::move(k), std::forward(obj)); - if (!ret.second) ret.first->second = std::forward(obj); - return ret; + template + std::pair insert_or_assign(key_arg &&k, M &&obj) { + return insert_or_assign_impl(std::forward(k), std::forward(obj)); } - template - iterator insert_or_assign(const_iterator position, const key_type &k, + template + iterator insert_or_assign(const_iterator hint, const key_arg &k, const M &obj) { - const std::pair ret = - this->tree_.insert_hint_unique(iterator(position), k, k, obj); - if (!ret.second) ret.first->second = obj; - return ret.first; + return insert_or_assign_hint_impl(hint, k, obj); } - template - iterator insert_or_assign(const_iterator position, key_type &&k, - const M &obj) { - const std::pair ret = this->tree_.insert_hint_unique( - iterator(position), k, std::move(k), obj); - if (!ret.second) ret.first->second = obj; - return ret.first; + template + iterator insert_or_assign(const_iterator hint, key_arg &&k, const M &obj) { + return insert_or_assign_hint_impl(hint, std::forward(k), obj); } - template - iterator insert_or_assign(const_iterator position, const key_type &k, - M &&obj) { - const std::pair ret = this->tree_.insert_hint_unique( - iterator(position), k, k, std::forward(obj)); - if (!ret.second) ret.first->second = std::forward(obj); - return ret.first; + template + iterator insert_or_assign(const_iterator hint, const key_arg &k, M &&obj) { + return insert_or_assign_hint_impl(hint, k, std::forward(obj)); } - template - iterator insert_or_assign(const_iterator position, key_type &&k, M &&obj) { - const std::pair ret = this->tree_.insert_hint_unique( - iterator(position), k, std::move(k), std::forward(obj)); - if (!ret.second) ret.first->second = std::forward(obj); - return ret.first; + template + iterator insert_or_assign(const_iterator hint, key_arg &&k, M &&obj) { + return insert_or_assign_hint_impl(hint, std::forward(k), + std::forward(obj)); } - template - std::pair try_emplace(const key_type &k, Args &&... args) { - return this->tree_.insert_unique( - k, std::piecewise_construct, std::forward_as_tuple(k), - std::forward_as_tuple(std::forward(args)...)); + + template ::value, int> = 0> + std::pair try_emplace(const key_arg &k, Args &&... args) { + return try_emplace_impl(k, std::forward(args)...); } - template - std::pair try_emplace(key_type &&k, Args &&... args) { - // Note: `key_ref` exists to avoid a ClangTidy warning about moving from `k` - // and then using `k` unsequenced. This is safe because the move is into a - // forwarding reference and insert_unique guarantees that `key` is never - // referenced after consuming `args`. - const key_type &key_ref = k; - return this->tree_.insert_unique( - key_ref, std::piecewise_construct, std::forward_as_tuple(std::move(k)), - std::forward_as_tuple(std::forward(args)...)); + template ::value, int> = 0> + std::pair try_emplace(key_arg &&k, Args &&... args) { + return try_emplace_impl(std::forward(k), std::forward(args)...); } - template - iterator try_emplace(const_iterator hint, const key_type &k, + template + iterator try_emplace(const_iterator hint, const key_arg &k, Args &&... args) { - return this->tree_ - .insert_hint_unique(iterator(hint), k, std::piecewise_construct, - std::forward_as_tuple(k), - std::forward_as_tuple(std::forward(args)...)) - .first; + return try_emplace_hint_impl(hint, k, std::forward(args)...); } - template - iterator try_emplace(const_iterator hint, key_type &&k, Args &&... args) { - // Note: `key_ref` exists to avoid a ClangTidy warning about moving from `k` - // and then using `k` unsequenced. This is safe because the move is into a - // forwarding reference and insert_hint_unique guarantees that `key` is - // never referenced after consuming `args`. - const key_type &key_ref = k; - return this->tree_ - .insert_hint_unique(iterator(hint), key_ref, std::piecewise_construct, - std::forward_as_tuple(std::move(k)), - std::forward_as_tuple(std::forward(args)...)) - .first; + template + iterator try_emplace(const_iterator hint, key_arg &&k, Args &&... args) { + return try_emplace_hint_impl(hint, std::forward(k), + std::forward(args)...); } - mapped_type &operator[](const key_type &k) { + + template + mapped_type &operator[](const key_arg &k) { return try_emplace(k).first->second; } - mapped_type &operator[](key_type &&k) { - return try_emplace(std::move(k)).first->second; + template + mapped_type &operator[](key_arg &&k) { + return try_emplace(std::forward(k)).first->second; } template @@ -513,6 +472,40 @@ class btree_map_container : public btree_set_container { base_internal::ThrowStdOutOfRange("absl::btree_map::at"); return it->second; } + + private: + // Note: when we call `std::forward(obj)` twice, it's safe because + // insert_unique/insert_hint_unique are guaranteed to not consume `obj` when + // `ret.second` is false. + template + std::pair insert_or_assign_impl(K &&k, M &&obj) { + const std::pair ret = + this->tree_.insert_unique(k, std::forward(k), std::forward(obj)); + if (!ret.second) ret.first->second = std::forward(obj); + return ret; + } + template + iterator insert_or_assign_hint_impl(const_iterator hint, K &&k, M &&obj) { + const std::pair ret = this->tree_.insert_hint_unique( + iterator(hint), k, std::forward(k), std::forward(obj)); + if (!ret.second) ret.first->second = std::forward(obj); + return ret.first; + } + + template + std::pair try_emplace_impl(K &&k, Args &&... args) { + return this->tree_.insert_unique( + k, std::piecewise_construct, std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)); + } + template + iterator try_emplace_hint_impl(const_iterator hint, K &&k, Args &&... args) { + return this->tree_ + .insert_hint_unique(iterator(hint), k, std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) + .first; + } }; // A common base class for btree_multiset and btree_multimap. @@ -566,11 +559,11 @@ class btree_multiset_container : public btree_container { iterator insert(value_type &&v) { return this->tree_.insert_multi(std::move(v)); } - iterator insert(const_iterator position, const value_type &v) { - return this->tree_.insert_hint_multi(iterator(position), v); + iterator insert(const_iterator hint, const value_type &v) { + return this->tree_.insert_hint_multi(iterator(hint), v); } - iterator insert(const_iterator position, value_type &&v) { - return this->tree_.insert_hint_multi(iterator(position), std::move(v)); + iterator insert(const_iterator hint, value_type &&v) { + return this->tree_.insert_hint_multi(iterator(hint), std::move(v)); } template void insert(InputIterator b, InputIterator e) { @@ -584,9 +577,9 @@ class btree_multiset_container : public btree_container { return this->tree_.insert_multi(init_type(std::forward(args)...)); } template - iterator emplace_hint(const_iterator position, Args &&... args) { + iterator emplace_hint(const_iterator hint, Args &&... args) { return this->tree_.insert_hint_multi( - iterator(position), init_type(std::forward(args)...)); + iterator(hint), init_type(std::forward(args)...)); } iterator insert(node_type &&node) { if (!node) return this->end(); diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h index 536ea398..92a61cc0 100644 --- a/absl/container/internal/container_memory.h +++ b/absl/container/internal/container_memory.h @@ -429,13 +429,6 @@ struct map_slot_policy { std::move(src->value)); } } - - template - static void move(Allocator* alloc, slot_type* first, slot_type* last, - slot_type* result) { - for (slot_type *src = first, *dest = result; src != last; ++src, ++dest) - move(alloc, src, dest); - } }; } // namespace container_internal -- cgit v1.2.3 From f2c9c663db28a8a898c1fc8c8e06ab9b93eb5610 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 9 Sep 2020 19:13:17 -0700 Subject: Export of internal Abseil changes -- cfb567ed02096320663d882d2c0c2fb7db7af1e4 by Derek Mauro : Upgrade to GCC 10.2.0, Bazel 3.5.0, and CMake 3.18.2 PiperOrigin-RevId: 330847323 -- 5dcb9ce14d92315163079366a91c43cbd5184ea4 by Evan Brown : Optimize equal_range() by avoiding the call to upper_bound() when possible. We need to support heterogeneous comparators that have different behavior when comparing key_type to non-key_type. See the new test. Also update the comment for `key_compare_to_adapter`. PiperOrigin-RevId: 330794444 -- 744405dbda5513527d74094a5c3b9db1e0927693 by Gennadiy Rozental : Introduce trampoline for friend access to avoid friending routines and classes from different namespace. PiperOrigin-RevId: 330773156 -- a195d1226576f8a7bb5671f3e42d1021b827fad9 by Abseil Team : Fix an incorrect version number test for std::variant availability in tvOs. PiperOrigin-RevId: 330759480 -- 58b02eb9159a577953676d9928cb26b30068b847 by Derek Mauro : Use c++20 instead of c++2a now that it is supported by GCC PiperOrigin-RevId: 330559797 GitOrigin-RevId: cfb567ed02096320663d882d2c0c2fb7db7af1e4 Change-Id: I0e0d68409c95da42f5609920155ba5694ade8df0 --- absl/base/config.h | 4 +-- absl/container/btree_test.cc | 34 +++++++++++++++++++ absl/container/internal/btree.h | 54 +++++++++++++++++++++++++------ absl/container/internal/btree_container.h | 2 ++ absl/flags/flag.h | 20 ++++++++---- absl/flags/internal/flag.h | 38 ++++++++++++---------- ci/linux_docker_containers.sh | 4 +-- ci/linux_gcc-latest_libstdcxx_bazel.sh | 2 +- ci/linux_gcc-latest_libstdcxx_cmake.sh | 2 +- 9 files changed, 121 insertions(+), 39 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index b1e095d3..c1d0494e 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -474,9 +474,9 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \ (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 120000) || \ + __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000) || \ (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \ - __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 50000)) + __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 120000)) #define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 1 #else #define ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 0 diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc index 43704206..1bfa0c20 100644 --- a/absl/container/btree_test.cc +++ b/absl/container/btree_test.cc @@ -2580,6 +2580,40 @@ TEST(Btree, NodeHandleMutableKeyAccess) { } #endif +struct MultiKey { + int i1; + int i2; +}; + +struct MultiKeyComp { + using is_transparent = void; + bool operator()(const MultiKey a, const MultiKey b) const { + if (a.i1 != b.i1) return a.i1 < b.i1; + return a.i2 < b.i2; + } + bool operator()(const int a, const MultiKey b) const { return a < b.i1; } + bool operator()(const MultiKey a, const int b) const { return a.i1 < b; } +}; + +// Test that when there's a heterogeneous comparator that behaves differently +// for some heterogeneous operators, we get equal_range() right. +TEST(Btree, MultiKeyEqualRange) { + absl::btree_set set; + + for (int i = 0; i < 100; ++i) { + for (int j = 0; j < 100; ++j) { + set.insert({i, j}); + } + } + + for (int i = 0; i < 100; ++i) { + auto equal_range = set.equal_range(i); + EXPECT_EQ(equal_range.first->i1, i); + EXPECT_EQ(equal_range.first->i2, 0); + EXPECT_EQ(std::distance(equal_range.first, equal_range.second), 100) << i; + } +} + } // namespace } // namespace container_internal ABSL_NAMESPACE_END diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h index 5986bb21..002ccc1e 100644 --- a/absl/container/internal/btree.h +++ b/absl/container/internal/btree.h @@ -137,15 +137,14 @@ struct StringBtreeDefaultGreater { }; // A helper class to convert a boolean comparison into a three-way "compare-to" -// comparison that returns a negative value to indicate less-than, zero to -// indicate equality and a positive value to indicate greater-than. This helper +// comparison that returns an `absl::weak_ordering`. This helper // class is specialized for less, greater, // less, greater, less, and // greater. // // key_compare_to_adapter is provided so that btree users // automatically get the more efficient compare-to code when using common -// google string types with common comparison functors. +// Abseil string types with common comparison functors. // These string-like specializations also turn on heterogeneous lookup by // default. template @@ -189,6 +188,9 @@ struct common_params { // If Compare is a common comparator for a string-like type, then we adapt it // to use heterogeneous lookup and to be a key-compare-to comparator. using key_compare = typename key_compare_to_adapter::type; + // True when key_compare has been adapted to StringBtreeDefault{Less,Greater}. + using is_key_compare_adapted = + absl::negation>; // A type which indicates if we have a key-compare-to functor or a plain old // key-compare functor. using is_key_compare_to = btree_is_key_compare_to; @@ -1015,6 +1017,8 @@ class btree { using is_key_compare_to = typename Params::is_key_compare_to; using init_type = typename Params::init_type; using field_type = typename node_type::field_type; + using is_multi_container = typename Params::is_multi_container; + using is_key_compare_adapted = typename Params::is_key_compare_adapted; // We use a static empty node for the root/leftmost/rightmost of empty btrees // in order to avoid branching in begin()/end(). @@ -1164,15 +1168,13 @@ class btree { } // Finds the range of values which compare equal to key. The first member of - // the returned pair is equal to lower_bound(key). The second member pair of - // the pair is equal to upper_bound(key). + // the returned pair is equal to lower_bound(key). The second member of the + // pair is equal to upper_bound(key). template - std::pair equal_range(const K &key) { - return {lower_bound(key), upper_bound(key)}; - } + std::pair equal_range(const K &key); template std::pair equal_range(const K &key) const { - return {lower_bound(key), upper_bound(key)}; + return const_cast(this)->equal_range(key); } // Inserts a value into the btree only if it does not already exist. The @@ -1890,6 +1892,40 @@ btree

::btree(const btree &other) copy_or_move_values_in_order(&other); } +template +template +auto btree

::equal_range(const K &key) -> std::pair { + const iterator lower = lower_bound(key); + // TODO(ezb): we should be able to avoid this comparison when there's a + // three-way comparator. + if (lower == end() || compare_keys(key, lower.key())) return {lower, lower}; + + const iterator next = std::next(lower); + // When the comparator is heterogeneous, we can't assume that comparison with + // non-`key_type` will be equivalent to `key_type` comparisons so there + // could be multiple equivalent keys even in a unique-container. But for + // heterogeneous comparisons from the default string adapted comparators, we + // don't need to worry about this. + if (!is_multi_container::value && + (std::is_same::value || is_key_compare_adapted::value)) { + // The next iterator after lower must point to a key greater than `key`. + // Note: if this assert fails, then it may indicate that the comparator does + // not meet the equivalence requirements for Compare + // (see https://en.cppreference.com/w/cpp/named_req/Compare). + assert(next == end() || compare_keys(key, next.key())); + return {lower, next}; + } + // Try once more to avoid the call to upper_bound() if there's only one + // equivalent key. This should prevent all calls to upper_bound() in cases of + // unique-containers with heterogeneous comparators in which all comparison + // operators are equivalent. + if (next == end() || compare_keys(key, next.key())) return {lower, next}; + + // In this case, we need to call upper_bound() to avoid worst case O(N) + // behavior if we were to iterate over equal keys. + return {lower, upper_bound(key)}; +} + template template auto btree

::insert_unique(const K &key, Args &&... args) diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h index 3b2e8a9e..137614f8 100644 --- a/absl/container/internal/btree_container.h +++ b/absl/container/internal/btree_container.h @@ -314,6 +314,8 @@ class btree_set_container : public btree_container { } // Deletion routines. + // TODO(ezb): we should support heterogeneous comparators that have different + // behavior for K!=key_type. template size_type erase(const key_arg &key) { return this->tree_.erase_unique(key); diff --git a/absl/flags/flag.h b/absl/flags/flag.h index cdac545b..a9cb2b79 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -144,11 +144,17 @@ class Flag { inline bool IsOfType() const { return GetImpl().template IsOfType(); } - T Get() const { return GetImpl().Get(); } - void Set(const T& v) { GetImpl().Set(v); } + T Get() const { + return flags_internal::FlagImplPeer::InvokeGet(GetImpl()); + } + void Set(const T& v) { + flags_internal::FlagImplPeer::InvokeSet(GetImpl(), v); + } void InvokeCallback() { GetImpl().InvokeCallback(); } - const CommandLineFlag& Reflect() const { return GetImpl().Reflect(); } + const CommandLineFlag& Reflect() const { + return flags_internal::FlagImplPeer::InvokeReflect(GetImpl()); + } // The data members are logically private, but they need to be public for // this to be an aggregate type. @@ -180,7 +186,7 @@ class Flag { // std::string first_name = absl::GetFlag(FLAGS_firstname); template ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag) { - return flag.Get(); + return flags_internal::FlagImplPeer::InvokeGet(flag); } // SetFlag() @@ -192,7 +198,7 @@ ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag& flag) { // but especially within performance-critical code. template void SetFlag(absl::Flag* flag, const T& v) { - flag->Set(v); + flags_internal::FlagImplPeer::InvokeSet(*flag, v); } // Overload of `SetFlag()` to allow callers to pass in a value that is @@ -201,7 +207,7 @@ void SetFlag(absl::Flag* flag, const T& v) { template void SetFlag(absl::Flag* flag, const V& v) { T value(v); - flag->Set(value); + flags_internal::FlagImplPeer::InvokeSet(*flag, value); } // GetFlagReflectionHandle() @@ -216,7 +222,7 @@ void SetFlag(absl::Flag* flag, const V& v) { template const CommandLineFlag& GetFlagReflectionHandle(const absl::Flag& f) { - return f.Reflect(); + return flags_internal::FlagImplPeer::InvokeReflect(f); } ABSL_NAMESPACE_END diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index 89e43ad7..370d8a02 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -632,20 +632,9 @@ class Flag { std::string CurrentValue() const { return impl_.CurrentValue(); } private: - template + template friend class FlagRegistrar; - -#if !defined(_MSC_VER) || defined(__clang__) - template - friend U absl::GetFlag(const flags_internal::Flag& flag); - template - friend void absl::SetFlag(flags_internal::Flag* flag, const U& v); - template - friend void absl::SetFlag(flags_internal::Flag* flag, const V& v); -#else - template - friend class absl::Flag; -#endif + friend class FlagImplPeer; T Get() const { // See implementation notes in CommandLineFlag::Get(). @@ -668,10 +657,6 @@ class Flag { impl_.Write(&v); } - template - friend const CommandLineFlag& absl::GetFlagReflectionHandle( - const absl::Flag& f); - // Access to the reflection. const CommandLineFlag& Reflect() const { return impl_; } @@ -683,6 +668,25 @@ class Flag { FlagValue value_; }; +/////////////////////////////////////////////////////////////////////////////// +// Trampoline for friend access + +class FlagImplPeer { + public: + template + static T InvokeGet(const FlagType& flag) { + return flag.Get(); + } + template + static void InvokeSet(FlagType& flag, const T& v) { + flag.Set(v); + } + template + static const CommandLineFlag& InvokeReflect(const FlagType& f) { + return f.Reflect(); + } +}; + /////////////////////////////////////////////////////////////////////////////// // Implementation of Flag value specific operations routine. template diff --git a/ci/linux_docker_containers.sh b/ci/linux_docker_containers.sh index 483ce2a2..e42fa58b 100644 --- a/ci/linux_docker_containers.sh +++ b/ci/linux_docker_containers.sh @@ -16,6 +16,6 @@ # Test scripts should source this file to get the identifiers. readonly LINUX_ALPINE_CONTAINER="gcr.io/google.com/absl-177019/alpine:20191016" -readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20200710" -readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20200710" +readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20200909" +readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20200909" readonly LINUX_GCC_49_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-4.9:20191018" diff --git a/ci/linux_gcc-latest_libstdcxx_bazel.sh b/ci/linux_gcc-latest_libstdcxx_bazel.sh index 3ec02262..cd15f710 100755 --- a/ci/linux_gcc-latest_libstdcxx_bazel.sh +++ b/ci/linux_gcc-latest_libstdcxx_bazel.sh @@ -25,7 +25,7 @@ if [[ -z ${ABSEIL_ROOT:-} ]]; then fi if [[ -z ${STD:-} ]]; then - STD="c++11 c++14 c++17 c++2a" + STD="c++11 c++14 c++17 c++20" fi if [[ -z ${COMPILATION_MODE:-} ]]; then diff --git a/ci/linux_gcc-latest_libstdcxx_cmake.sh b/ci/linux_gcc-latest_libstdcxx_cmake.sh index db5f6918..1ba02b26 100755 --- a/ci/linux_gcc-latest_libstdcxx_cmake.sh +++ b/ci/linux_gcc-latest_libstdcxx_cmake.sh @@ -27,7 +27,7 @@ if [[ -z ${ABSEIL_ROOT:-} ]]; then fi if [[ -z ${ABSL_CMAKE_CXX_STANDARDS:-} ]]; then - ABSL_CMAKE_CXX_STANDARDS="11 14 17" + ABSL_CMAKE_CXX_STANDARDS="11 14 17 20" fi if [[ -z ${ABSL_CMAKE_BUILD_TYPES:-} ]]; then -- cgit v1.2.3 From d1de75bf540f091b4dfc860713d556e578c0f158 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 25 Sep 2020 10:29:25 -0700 Subject: Export of internal Abseil changes -- f50d25c8f8491ef7031cbbcad78edd15f98c2bd1 by Abseil Team : Add myriad2 to HAVE_MMAP Remove mutex_nonprod and associated defines. PiperOrigin-RevId: 333759830 -- 25ef4c577ea983aa3fcd6cfe2af6cdc62a06f520 by Samuel Benzaquen : Internal refactor. Represent the data with a union to allow for better constexpr support in the future. PiperOrigin-RevId: 333756733 GitOrigin-RevId: f50d25c8f8491ef7031cbbcad78edd15f98c2bd1 Change-Id: Ieecd2c47cb20de638726eb3f9fc2e5682d05dcca --- absl/base/config.h | 2 +- absl/strings/cord.cc | 85 +++---- absl/strings/cord.h | 95 ++++--- absl/strings/internal/cord_internal.h | 39 +++ absl/synchronization/BUILD.bazel | 6 +- absl/synchronization/CMakeLists.txt | 1 - absl/synchronization/internal/mutex_nonprod.cc | 325 ------------------------ absl/synchronization/internal/mutex_nonprod.inc | 249 ------------------ absl/synchronization/mutex.h | 34 --- absl/synchronization/mutex_test.cc | 4 - 10 files changed, 128 insertions(+), 712 deletions(-) delete mode 100644 absl/synchronization/internal/mutex_nonprod.cc delete mode 100644 absl/synchronization/internal/mutex_nonprod.inc (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index c1d0494e..3f7f32b9 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -364,7 +364,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \ defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) || \ - defined(__ASYLO__) + defined(__ASYLO__) || defined(__myriad2__) #define ABSL_HAVE_MMAP 1 #endif diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc index 763dcc45..5092fd14 100644 --- a/absl/strings/cord.cc +++ b/absl/strings/cord.cc @@ -50,16 +50,10 @@ using ::absl::cord_internal::CordRepConcat; using ::absl::cord_internal::CordRepExternal; using ::absl::cord_internal::CordRepSubstring; -// Various representations that we allow -enum CordRepKind { - CONCAT = 0, - EXTERNAL = 1, - SUBSTRING = 2, - - // We have different tags for different sized flat arrays, - // starting with FLAT - FLAT = 3, -}; +using ::absl::cord_internal::CONCAT; +using ::absl::cord_internal::EXTERNAL; +using ::absl::cord_internal::FLAT; +using ::absl::cord_internal::SUBSTRING; namespace cord_internal { @@ -447,48 +441,49 @@ inline void Cord::InlineRep::set_data(const char* data, size_t n, bool nullify_tail) { static_assert(kMaxInline == 15, "set_data is hard-coded for a length of 15"); - cord_internal::SmallMemmove(data_, data, n, nullify_tail); - data_[kMaxInline] = static_cast(n); + cord_internal::SmallMemmove(data_.as_chars, data, n, nullify_tail); + set_tagged_size(static_cast(n)); } inline char* Cord::InlineRep::set_data(size_t n) { assert(n <= kMaxInline); - memset(data_, 0, sizeof(data_)); - data_[kMaxInline] = static_cast(n); - return data_; + ResetToEmpty(); + set_tagged_size(static_cast(n)); + return data_.as_chars; } inline CordRep* Cord::InlineRep::force_tree(size_t extra_hint) { - size_t len = data_[kMaxInline]; - CordRep* result; + size_t len = tagged_size(); if (len > kMaxInline) { - memcpy(&result, data_, sizeof(result)); - } else { - result = NewFlat(len + extra_hint); - result->length = len; - memcpy(result->data, data_, len); - set_tree(result); + return data_.as_tree.rep; } + + CordRep* result = NewFlat(len + extra_hint); + result->length = len; + static_assert(kMinFlatLength >= sizeof(data_.as_chars), ""); + memcpy(result->data, data_.as_chars, sizeof(data_.as_chars)); + set_tree(result); return result; } inline void Cord::InlineRep::reduce_size(size_t n) { - size_t tag = data_[kMaxInline]; + size_t tag = tagged_size(); assert(tag <= kMaxInline); assert(tag >= n); tag -= n; - memset(data_ + tag, 0, n); - data_[kMaxInline] = static_cast(tag); + memset(data_.as_chars + tag, 0, n); + set_tagged_size(static_cast(tag)); } inline void Cord::InlineRep::remove_prefix(size_t n) { - cord_internal::SmallMemmove(data_, data_ + n, data_[kMaxInline] - n); + cord_internal::SmallMemmove(data_.as_chars, data_.as_chars + n, + tagged_size() - n); reduce_size(n); } void Cord::InlineRep::AppendTree(CordRep* tree) { if (tree == nullptr) return; - size_t len = data_[kMaxInline]; + size_t len = tagged_size(); if (len == 0) { set_tree(tree); } else { @@ -498,7 +493,7 @@ void Cord::InlineRep::AppendTree(CordRep* tree) { void Cord::InlineRep::PrependTree(CordRep* tree) { assert(tree != nullptr); - size_t len = data_[kMaxInline]; + size_t len = tagged_size(); if (len == 0) { set_tree(tree); } else { @@ -554,11 +549,11 @@ void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, } // Try to fit in the inline buffer if possible. - size_t inline_length = data_[kMaxInline]; + size_t inline_length = tagged_size(); if (inline_length < kMaxInline && max_length <= kMaxInline - inline_length) { - *region = data_ + inline_length; + *region = data_.as_chars + inline_length; *size = max_length; - data_[kMaxInline] = static_cast(inline_length + max_length); + set_tagged_size(static_cast(inline_length + max_length)); return; } @@ -582,11 +577,11 @@ void Cord::InlineRep::GetAppendRegion(char** region, size_t* size) { const size_t max_length = std::numeric_limits::max(); // Try to fit in the inline buffer if possible. - size_t inline_length = data_[kMaxInline]; + size_t inline_length = tagged_size(); if (inline_length < kMaxInline) { - *region = data_ + inline_length; + *region = data_.as_chars + inline_length; *size = kMaxInline - inline_length; - data_[kMaxInline] = kMaxInline; + set_tagged_size(kMaxInline); return; } @@ -621,7 +616,7 @@ static bool RepMemoryUsageLeaf(const CordRep* rep, size_t* total_mem_usage) { void Cord::InlineRep::AssignSlow(const Cord::InlineRep& src) { ClearSlow(); - memcpy(data_, src.data_, sizeof(data_)); + data_ = src.data_; if (is_tree()) { Ref(tree()); } @@ -631,7 +626,7 @@ void Cord::InlineRep::ClearSlow() { if (is_tree()) { Unref(tree()); } - memset(data_, 0, sizeof(data_)); + ResetToEmpty(); } // -------------------------------------------------------------------- @@ -735,11 +730,11 @@ template Cord& Cord::operator=(std::string&& src); void Cord::InlineRep::AppendArray(const char* src_data, size_t src_size) { if (src_size == 0) return; // memcpy(_, nullptr, 0) is undefined. // Try to fit in the inline buffer if possible. - size_t inline_length = data_[kMaxInline]; + size_t inline_length = tagged_size(); if (inline_length < kMaxInline && src_size <= kMaxInline - inline_length) { // Append new data to embedded array - data_[kMaxInline] = static_cast(inline_length + src_size); - memcpy(data_ + inline_length, src_data, src_size); + set_tagged_size(static_cast(inline_length + src_size)); + memcpy(data_.as_chars + inline_length, src_data, src_size); return; } @@ -762,7 +757,7 @@ void Cord::InlineRep::AppendArray(const char* src_data, size_t src_size) { const size_t size2 = inline_length + src_size / 10; root = NewFlat(std::max(size1, size2)); appended = std::min(src_size, TagToLength(root->tag) - inline_length); - memcpy(root->data, data_, inline_length); + memcpy(root->data, data_.as_chars, inline_length); memcpy(root->data + inline_length, src_data, appended); root->length = inline_length + appended; set_tree(root); @@ -1071,7 +1066,7 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const { } else if (new_size <= InlineRep::kMaxInline) { Cord::ChunkIterator it = chunk_begin(); it.AdvanceBytes(pos); - char* dest = sub_cord.contents_.data_; + char* dest = sub_cord.contents_.data_.as_chars; size_t remaining_size = new_size; while (remaining_size > it->size()) { cord_internal::SmallMemmove(dest, it->data(), it->size()); @@ -1080,7 +1075,7 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const { ++it; } cord_internal::SmallMemmove(dest, it->data(), remaining_size); - sub_cord.contents_.data_[InlineRep::kMaxInline] = new_size; + sub_cord.contents_.set_tagged_size(new_size); } else { sub_cord.contents_.set_tree(NewSubRange(tree, pos, new_size)); } @@ -1269,9 +1264,9 @@ bool ComputeCompareResult(int memcmp_res) { // Helper routine. Locates the first flat chunk of the Cord without // initializing the iterator. inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const { - size_t n = data_[kMaxInline]; + size_t n = tagged_size(); if (n <= kMaxInline) { - return absl::string_view(data_, n); + return absl::string_view(data_.as_chars, n); } CordRep* node = tree(); diff --git a/absl/strings/cord.h b/absl/strings/cord.h index b8b251b0..653a1181 100644 --- a/absl/strings/cord.h +++ b/absl/strings/cord.h @@ -644,14 +644,12 @@ class Cord { // InlineRep holds either a tree pointer, or an array of kMaxInline bytes. class InlineRep { public: - static constexpr unsigned char kMaxInline = 15; + static constexpr unsigned char kMaxInline = cord_internal::kMaxInline; static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*), ""); - // Tag byte & kMaxInline means we are storing a pointer. - static constexpr unsigned char kTreeFlag = 1 << 4; - // Tag byte & kProfiledFlag means we are profiling the Cord. - static constexpr unsigned char kProfiledFlag = 1 << 5; + static constexpr unsigned char kTreeFlag = cord_internal::kTreeFlag; + static constexpr unsigned char kProfiledFlag = cord_internal::kProfiledFlag; - constexpr InlineRep() : data_{} {} + constexpr InlineRep() : data_() {} InlineRep(const InlineRep& src); InlineRep(InlineRep&& src); InlineRep& operator=(const InlineRep& src); @@ -684,16 +682,16 @@ class Cord { void GetAppendRegion(char** region, size_t* size, size_t max_length); void GetAppendRegion(char** region, size_t* size); bool IsSame(const InlineRep& other) const { - return memcmp(data_, other.data_, sizeof(data_)) == 0; + return memcmp(&data_, &other.data_, sizeof(data_)) == 0; } int BitwiseCompare(const InlineRep& other) const { uint64_t x, y; - // Use memcpy to avoid anti-aliasing issues. - memcpy(&x, data_, sizeof(x)); - memcpy(&y, other.data_, sizeof(y)); + // Use memcpy to avoid aliasing issues. + memcpy(&x, &data_, sizeof(x)); + memcpy(&y, &other.data_, sizeof(y)); if (x == y) { - memcpy(&x, data_ + 8, sizeof(x)); - memcpy(&y, other.data_ + 8, sizeof(y)); + memcpy(&x, reinterpret_cast(&data_) + 8, sizeof(x)); + memcpy(&y, reinterpret_cast(&other.data_) + 8, sizeof(y)); if (x == y) return 0; } return absl::big_endian::FromHost64(x) < absl::big_endian::FromHost64(y) @@ -706,16 +704,16 @@ class Cord { // to 15 bytes does not cause a memory allocation. absl::strings_internal::STLStringResizeUninitialized(dst, sizeof(data_) - 1); - memcpy(&(*dst)[0], data_, sizeof(data_) - 1); + memcpy(&(*dst)[0], &data_, sizeof(data_) - 1); // erase is faster than resize because the logic for memory allocation is // not needed. - dst->erase(data_[kMaxInline]); + dst->erase(tagged_size()); } // Copies the inline contents into `dst`. Assumes the cord is not empty. void CopyToArray(char* dst) const; - bool is_tree() const { return data_[kMaxInline] > kMaxInline; } + bool is_tree() const { return tagged_size() > kMaxInline; } private: friend class Cord; @@ -724,10 +722,18 @@ class Cord { // Unrefs the tree, stops profiling, and zeroes the contents void ClearSlow(); - // If the data has length <= kMaxInline, we store it in data_[0..len-1], - // and store the length in data_[kMaxInline]. Else we store it in a tree - // and store a pointer to that tree in data_[0..sizeof(CordRep*)-1]. - alignas(absl::cord_internal::CordRep*) char data_[kMaxInline + 1]; + void ResetToEmpty() { data_ = {}; } + + // This uses reinterpret_cast instead of the union to avoid accessing the + // inactive union element. The tagged size is not a common prefix. + void set_tagged_size(char new_tag) { + reinterpret_cast(&data_)[kMaxInline] = new_tag; + } + char tagged_size() const { + return reinterpret_cast(&data_)[kMaxInline]; + } + + cord_internal::InlineData data_; }; InlineRep contents_; @@ -879,12 +885,12 @@ Cord MakeCordFromExternal(absl::string_view data, Releaser&& releaser) { } inline Cord::InlineRep::InlineRep(const Cord::InlineRep& src) { - cord_internal::SmallMemmove(data_, src.data_, sizeof(data_)); + data_ = src.data_; } inline Cord::InlineRep::InlineRep(Cord::InlineRep&& src) { - memcpy(data_, src.data_, sizeof(data_)); - memset(src.data_, 0, sizeof(data_)); + data_ = src.data_; + src.ResetToEmpty(); } inline Cord::InlineRep& Cord::InlineRep::operator=(const Cord::InlineRep& src) { @@ -892,7 +898,7 @@ inline Cord::InlineRep& Cord::InlineRep::operator=(const Cord::InlineRep& src) { return *this; } if (!is_tree() && !src.is_tree()) { - cord_internal::SmallMemmove(data_, src.data_, sizeof(data_)); + data_ = src.data_; return *this; } AssignSlow(src); @@ -904,8 +910,8 @@ inline Cord::InlineRep& Cord::InlineRep::operator=( if (is_tree()) { ClearSlow(); } - memcpy(data_, src.data_, sizeof(data_)); - memset(src.data_, 0, sizeof(data_)); + data_ = src.data_; + src.ResetToEmpty(); return *this; } @@ -914,43 +920,39 @@ inline void Cord::InlineRep::Swap(Cord::InlineRep* rhs) { return; } - Cord::InlineRep tmp; - cord_internal::SmallMemmove(tmp.data_, data_, sizeof(data_)); - cord_internal::SmallMemmove(data_, rhs->data_, sizeof(data_)); - cord_internal::SmallMemmove(rhs->data_, tmp.data_, sizeof(data_)); + std::swap(data_, rhs->data_); } inline const char* Cord::InlineRep::data() const { - return is_tree() ? nullptr : data_; + return is_tree() ? nullptr : data_.as_chars; } inline absl::cord_internal::CordRep* Cord::InlineRep::tree() const { if (is_tree()) { - absl::cord_internal::CordRep* rep; - memcpy(&rep, data_, sizeof(rep)); - return rep; + return data_.as_tree.rep; } else { return nullptr; } } -inline bool Cord::InlineRep::empty() const { return data_[kMaxInline] == 0; } +inline bool Cord::InlineRep::empty() const { return tagged_size() == 0; } inline size_t Cord::InlineRep::size() const { - const char tag = data_[kMaxInline]; + const char tag = tagged_size(); if (tag <= kMaxInline) return tag; return static_cast(tree()->length); } inline void Cord::InlineRep::set_tree(absl::cord_internal::CordRep* rep) { if (rep == nullptr) { - memset(data_, 0, sizeof(data_)); + ResetToEmpty(); } else { bool was_tree = is_tree(); - memcpy(data_, &rep, sizeof(rep)); - memset(data_ + sizeof(rep), 0, sizeof(data_) - sizeof(rep) - 1); + data_.as_tree = {rep, {}, tagged_size()}; if (!was_tree) { - data_[kMaxInline] = kTreeFlag; + // If we were not a tree already, set the tag. + // Otherwise, leave it alone because it might have the profile bit on. + set_tagged_size(kTreeFlag); } } } @@ -961,25 +963,20 @@ inline void Cord::InlineRep::replace_tree(absl::cord_internal::CordRep* rep) { set_tree(rep); return; } - memcpy(data_, &rep, sizeof(rep)); - memset(data_ + sizeof(rep), 0, sizeof(data_) - sizeof(rep) - 1); + data_.as_tree = {rep, {}, tagged_size()}; } inline absl::cord_internal::CordRep* Cord::InlineRep::clear() { - const char tag = data_[kMaxInline]; - absl::cord_internal::CordRep* result = nullptr; - if (tag > kMaxInline) { - memcpy(&result, data_, sizeof(result)); - } - memset(data_, 0, sizeof(data_)); // Clear the cord + absl::cord_internal::CordRep* result = tree(); + ResetToEmpty(); return result; } inline void Cord::InlineRep::CopyToArray(char* dst) const { assert(!is_tree()); - size_t n = data_[kMaxInline]; + size_t n = tagged_size(); assert(n != 0); - cord_internal::SmallMemmove(dst, data_, n); + cord_internal::SmallMemmove(dst, data_.as_chars, n); } constexpr inline Cord::Cord() noexcept {} diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index d456eef8..00b9baa9 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h @@ -85,6 +85,17 @@ struct CordRepConcat; struct CordRepSubstring; struct CordRepExternal; +// Various representations that we allow +enum CordRepKind { + CONCAT = 0, + EXTERNAL = 1, + SUBSTRING = 2, + + // We have different tags for different sized flat arrays, + // starting with FLAT + FLAT = 3, +}; + struct CordRep { // The following three fields have to be less than 32 bytes since // that is the smallest supported flat node size. @@ -167,6 +178,34 @@ struct CordRepExternalImpl } }; +enum { + kMaxInline = 15, + // Tag byte & kMaxInline means we are storing a pointer. + kTreeFlag = 1 << 4, + // Tag byte & kProfiledFlag means we are profiling the Cord. + kProfiledFlag = 1 << 5 +}; + +// If the data has length <= kMaxInline, we store it in `as_chars`, and +// store the size in `tagged_size`. +// Else we store it in a tree and store a pointer to that tree in +// `as_tree.rep` and store a tag in `tagged_size`. +struct AsTree { + absl::cord_internal::CordRep* rep; + char padding[kMaxInline + 1 - sizeof(absl::cord_internal::CordRep*) - 1]; + char tagged_size; +}; +union InlineData { + constexpr InlineData() : as_chars{} {} + explicit constexpr InlineData(AsTree tree) : as_tree(tree) {} + + AsTree as_tree; + char as_chars[kMaxInline + 1]; +}; +static_assert(sizeof(InlineData) == kMaxInline + 1, ""); +static_assert(sizeof(AsTree) == sizeof(InlineData), ""); +static_assert(offsetof(AsTree, tagged_size) == kMaxInline, ""); + } // namespace cord_internal ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index 4d4d6806..b2df4131 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -73,15 +73,13 @@ cc_library( "internal/create_thread_identity.cc", "internal/per_thread_sem.cc", "internal/waiter.cc", + "mutex.cc", "notification.cc", - ] + select({ - "//conditions:default": ["mutex.cc"], - }), + ], hdrs = [ "barrier.h", "blocking_counter.h", "internal/create_thread_identity.h", - "internal/mutex_nonprod.inc", "internal/per_thread_sem.h", "internal/waiter.h", "mutex.h", diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt index e5bc52fb..c255b03e 100644 --- a/absl/synchronization/CMakeLists.txt +++ b/absl/synchronization/CMakeLists.txt @@ -52,7 +52,6 @@ absl_cc_library( "barrier.h" "blocking_counter.h" "internal/create_thread_identity.h" - "internal/mutex_nonprod.inc" "internal/per_thread_sem.h" "internal/waiter.h" "mutex.h" diff --git a/absl/synchronization/internal/mutex_nonprod.cc b/absl/synchronization/internal/mutex_nonprod.cc deleted file mode 100644 index 334c3bc0..00000000 --- a/absl/synchronization/internal/mutex_nonprod.cc +++ /dev/null @@ -1,325 +0,0 @@ -// Copyright 2017 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. - -// Implementation of a small subset of Mutex and CondVar functionality -// for platforms where the production implementation hasn't been fully -// ported yet. - -#include "absl/synchronization/mutex.h" - -#if defined(_WIN32) -#include // NOLINT(build/c++11) -#else -#include -#include -#endif - -#include - -#include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/time/time.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -void SetMutexDeadlockDetectionMode(OnDeadlockCycle) {} -void EnableMutexInvariantDebugging(bool) {} - -namespace synchronization_internal { - -namespace { - -// Return the current time plus the timeout. -absl::Time DeadlineFromTimeout(absl::Duration timeout) { - return absl::Now() + timeout; -} - -// Limit the deadline to a positive, 32-bit time_t value to accommodate -// implementation restrictions. This also deals with InfinitePast and -// InfiniteFuture. -absl::Time LimitedDeadline(absl::Time deadline) { - deadline = std::max(absl::FromTimeT(0), deadline); - deadline = std::min(deadline, absl::FromTimeT(0x7fffffff)); - return deadline; -} - -} // namespace - -#if defined(_WIN32) - -MutexImpl::MutexImpl() {} - -MutexImpl::~MutexImpl() { - if (locked_) { - std_mutex_.unlock(); - } -} - -void MutexImpl::Lock() { - std_mutex_.lock(); - locked_ = true; -} - -bool MutexImpl::TryLock() { - bool locked = std_mutex_.try_lock(); - if (locked) locked_ = true; - return locked; -} - -void MutexImpl::Unlock() { - locked_ = false; - released_.SignalAll(); - std_mutex_.unlock(); -} - -CondVarImpl::CondVarImpl() {} - -CondVarImpl::~CondVarImpl() {} - -void CondVarImpl::Signal() { std_cv_.notify_one(); } - -void CondVarImpl::SignalAll() { std_cv_.notify_all(); } - -void CondVarImpl::Wait(MutexImpl* mu) { - mu->released_.SignalAll(); - std_cv_.wait(mu->std_mutex_); -} - -bool CondVarImpl::WaitWithDeadline(MutexImpl* mu, absl::Time deadline) { - mu->released_.SignalAll(); - time_t when = ToTimeT(deadline); - int64_t nanos = ToInt64Nanoseconds(deadline - absl::FromTimeT(when)); - std::chrono::system_clock::time_point deadline_tp = - std::chrono::system_clock::from_time_t(when) + - std::chrono::duration_cast( - std::chrono::nanoseconds(nanos)); - auto deadline_since_epoch = - std::chrono::duration_cast>( - deadline_tp - std::chrono::system_clock::from_time_t(0)); - return std_cv_.wait_until(mu->std_mutex_, deadline_tp) == - std::cv_status::timeout; -} - -#else // ! _WIN32 - -MutexImpl::MutexImpl() { - ABSL_RAW_CHECK(pthread_mutex_init(&pthread_mutex_, nullptr) == 0, - "pthread error"); -} - -MutexImpl::~MutexImpl() { - if (locked_) { - ABSL_RAW_CHECK(pthread_mutex_unlock(&pthread_mutex_) == 0, "pthread error"); - } - ABSL_RAW_CHECK(pthread_mutex_destroy(&pthread_mutex_) == 0, "pthread error"); -} - -void MutexImpl::Lock() { - ABSL_RAW_CHECK(pthread_mutex_lock(&pthread_mutex_) == 0, "pthread error"); - locked_ = true; -} - -bool MutexImpl::TryLock() { - bool locked = (0 == pthread_mutex_trylock(&pthread_mutex_)); - if (locked) locked_ = true; - return locked; -} - -void MutexImpl::Unlock() { - locked_ = false; - released_.SignalAll(); - ABSL_RAW_CHECK(pthread_mutex_unlock(&pthread_mutex_) == 0, "pthread error"); -} - -CondVarImpl::CondVarImpl() { - ABSL_RAW_CHECK(pthread_cond_init(&pthread_cv_, nullptr) == 0, - "pthread error"); -} - -CondVarImpl::~CondVarImpl() { - ABSL_RAW_CHECK(pthread_cond_destroy(&pthread_cv_) == 0, "pthread error"); -} - -void CondVarImpl::Signal() { - ABSL_RAW_CHECK(pthread_cond_signal(&pthread_cv_) == 0, "pthread error"); -} - -void CondVarImpl::SignalAll() { - ABSL_RAW_CHECK(pthread_cond_broadcast(&pthread_cv_) == 0, "pthread error"); -} - -void CondVarImpl::Wait(MutexImpl* mu) { - mu->released_.SignalAll(); - ABSL_RAW_CHECK(pthread_cond_wait(&pthread_cv_, &mu->pthread_mutex_) == 0, - "pthread error"); -} - -bool CondVarImpl::WaitWithDeadline(MutexImpl* mu, absl::Time deadline) { - mu->released_.SignalAll(); - struct timespec ts = ToTimespec(deadline); - int rc = pthread_cond_timedwait(&pthread_cv_, &mu->pthread_mutex_, &ts); - if (rc == ETIMEDOUT) return true; - ABSL_RAW_CHECK(rc == 0, "pthread error"); - return false; -} - -#endif // ! _WIN32 - -void MutexImpl::Await(const Condition& cond) { - if (cond.Eval()) return; - released_.SignalAll(); - do { - released_.Wait(this); - } while (!cond.Eval()); -} - -bool MutexImpl::AwaitWithDeadline(const Condition& cond, absl::Time deadline) { - if (cond.Eval()) return true; - released_.SignalAll(); - while (true) { - if (released_.WaitWithDeadline(this, deadline)) return false; - if (cond.Eval()) return true; - } -} - -} // namespace synchronization_internal - -Mutex::Mutex() {} - -Mutex::~Mutex() {} - -void Mutex::Lock() { impl()->Lock(); } - -void Mutex::Unlock() { impl()->Unlock(); } - -bool Mutex::TryLock() { return impl()->TryLock(); } - -void Mutex::ReaderLock() { Lock(); } - -void Mutex::ReaderUnlock() { Unlock(); } - -void Mutex::Await(const Condition& cond) { impl()->Await(cond); } - -void Mutex::LockWhen(const Condition& cond) { - Lock(); - Await(cond); -} - -bool Mutex::AwaitWithDeadline(const Condition& cond, absl::Time deadline) { - return impl()->AwaitWithDeadline( - cond, synchronization_internal::LimitedDeadline(deadline)); -} - -bool Mutex::AwaitWithTimeout(const Condition& cond, absl::Duration timeout) { - return AwaitWithDeadline( - cond, synchronization_internal::DeadlineFromTimeout(timeout)); -} - -bool Mutex::LockWhenWithDeadline(const Condition& cond, absl::Time deadline) { - Lock(); - return AwaitWithDeadline(cond, deadline); -} - -bool Mutex::LockWhenWithTimeout(const Condition& cond, absl::Duration timeout) { - return LockWhenWithDeadline( - cond, synchronization_internal::DeadlineFromTimeout(timeout)); -} - -void Mutex::ReaderLockWhen(const Condition& cond) { - ReaderLock(); - Await(cond); -} - -bool Mutex::ReaderLockWhenWithTimeout(const Condition& cond, - absl::Duration timeout) { - return LockWhenWithTimeout(cond, timeout); -} -bool Mutex::ReaderLockWhenWithDeadline(const Condition& cond, - absl::Time deadline) { - return LockWhenWithDeadline(cond, deadline); -} - -void Mutex::EnableDebugLog(const char*) {} -void Mutex::EnableInvariantDebugging(void (*)(void*), void*) {} -void Mutex::ForgetDeadlockInfo() {} -void Mutex::AssertHeld() const {} -void Mutex::AssertReaderHeld() const {} -void Mutex::AssertNotHeld() const {} - -CondVar::CondVar() {} - -CondVar::~CondVar() {} - -void CondVar::Signal() { impl()->Signal(); } - -void CondVar::SignalAll() { impl()->SignalAll(); } - -void CondVar::Wait(Mutex* mu) { return impl()->Wait(mu->impl()); } - -bool CondVar::WaitWithDeadline(Mutex* mu, absl::Time deadline) { - return impl()->WaitWithDeadline( - mu->impl(), synchronization_internal::LimitedDeadline(deadline)); -} - -bool CondVar::WaitWithTimeout(Mutex* mu, absl::Duration timeout) { - return WaitWithDeadline(mu, absl::Now() + timeout); -} - -void CondVar::EnableDebugLog(const char*) {} - -#ifdef ABSL_HAVE_THREAD_SANITIZER -extern "C" void __tsan_read1(void *addr); -#else -#define __tsan_read1(addr) // do nothing if TSan not enabled -#endif - -// A function that just returns its argument, dereferenced -static bool Dereference(void *arg) { - // ThreadSanitizer does not instrument this file for memory accesses. - // This function dereferences a user variable that can participate - // in a data race, so we need to manually tell TSan about this memory access. - __tsan_read1(arg); - return *(static_cast(arg)); -} - -Condition::Condition() {} // null constructor, used for kTrue only -const Condition Condition::kTrue; - -Condition::Condition(bool (*func)(void *), void *arg) - : eval_(&CallVoidPtrFunction), - function_(func), - method_(nullptr), - arg_(arg) {} - -bool Condition::CallVoidPtrFunction(const Condition *c) { - return (*c->function_)(c->arg_); -} - -Condition::Condition(const bool *cond) - : eval_(CallVoidPtrFunction), - function_(Dereference), - method_(nullptr), - // const_cast is safe since Dereference does not modify arg - arg_(const_cast(cond)) {} - -bool Condition::Eval() const { - // eval_ == null for kTrue - return (this->eval_ == nullptr) || (*this->eval_)(this); -} - -void RegisterSymbolizer(bool (*)(const void*, char*, int)) {} - -ABSL_NAMESPACE_END -} // namespace absl diff --git a/absl/synchronization/internal/mutex_nonprod.inc b/absl/synchronization/internal/mutex_nonprod.inc deleted file mode 100644 index d83bc8a9..00000000 --- a/absl/synchronization/internal/mutex_nonprod.inc +++ /dev/null @@ -1,249 +0,0 @@ -// Do not include. This is an implementation detail of base/mutex.h. -// -// Declares three classes: -// -// base::internal::MutexImpl - implementation helper for Mutex -// base::internal::CondVarImpl - implementation helper for CondVar -// base::internal::SynchronizationStorage - implementation helper for -// Mutex, CondVar - -#include - -#if defined(_WIN32) -#include -#include -#else -#include -#endif - -#include "absl/base/call_once.h" -#include "absl/time/time.h" - -// Declare that Mutex::ReaderLock is actually Lock(). Intended primarily -// for tests, and even then as a last resort. -#ifdef ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE -#error ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE cannot be directly set -#else -#define ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE 1 -#endif - -// Declare that Mutex::EnableInvariantDebugging is not implemented. -// Intended primarily for tests, and even then as a last resort. -#ifdef ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED -#error ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED cannot be directly set -#else -#define ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED 1 -#endif - -namespace absl { -ABSL_NAMESPACE_BEGIN -class Condition; - -namespace synchronization_internal { - -class MutexImpl; - -// Do not use this implementation detail of CondVar. Provides most of the -// implementation, but should not be placed directly in static storage -// because it will not linker initialize properly. See -// SynchronizationStorage below for what we mean by linker -// initialization. -class CondVarImpl { - public: - CondVarImpl(); - CondVarImpl(const CondVarImpl&) = delete; - CondVarImpl& operator=(const CondVarImpl&) = delete; - ~CondVarImpl(); - - void Signal(); - void SignalAll(); - void Wait(MutexImpl* mutex); - bool WaitWithDeadline(MutexImpl* mutex, absl::Time deadline); - - private: -#if defined(_WIN32) - std::condition_variable_any std_cv_; -#else - pthread_cond_t pthread_cv_; -#endif -}; - -// Do not use this implementation detail of Mutex. Provides most of the -// implementation, but should not be placed directly in static storage -// because it will not linker initialize properly. See -// SynchronizationStorage below for what we mean by linker -// initialization. -class MutexImpl { - public: - MutexImpl(); - MutexImpl(const MutexImpl&) = delete; - MutexImpl& operator=(const MutexImpl&) = delete; - ~MutexImpl(); - - void Lock(); - bool TryLock(); - void Unlock(); - void Await(const Condition& cond); - bool AwaitWithDeadline(const Condition& cond, absl::Time deadline); - - private: - friend class CondVarImpl; - -#if defined(_WIN32) - std::mutex std_mutex_; -#else - pthread_mutex_t pthread_mutex_; -#endif - - // True if the underlying mutex is locked. If the destructor is entered - // while locked_, the underlying mutex is unlocked. Mutex supports - // destruction while locked, but the same is undefined behavior for both - // pthread_mutex_t and std::mutex. - bool locked_ = false; - - // Signaled before releasing the lock, in support of Await. - CondVarImpl released_; -}; - -// Do not use this implementation detail of CondVar and Mutex. A storage -// space for T that supports a LinkerInitialized constructor. T must -// have a default constructor, which is called by the first call to -// get(). T's destructor is never called if the LinkerInitialized -// constructor is called. -// -// Objects constructed with the default constructor are constructed and -// destructed like any other object, and should never be allocated in -// static storage. -// -// Objects constructed with the LinkerInitialized constructor should -// always be in static storage. For such objects, calls to get() are always -// valid, except from signal handlers. -// -// Note that this implementation relies on undefined language behavior that -// are known to hold for the set of supported compilers. An analysis -// follows. -// -// From the C++11 standard: -// -// [basic.life] says an object has non-trivial initialization if it is of -// class type and it is initialized by a constructor other than a trivial -// default constructor. (the LinkerInitialized constructor is -// non-trivial) -// -// [basic.life] says the lifetime of an object with a non-trivial -// constructor begins when the call to the constructor is complete. -// -// [basic.life] says the lifetime of an object with non-trivial destructor -// ends when the call to the destructor begins. -// -// [basic.life] p5 specifies undefined behavior when accessing non-static -// members of an instance outside its -// lifetime. (SynchronizationStorage::get() access non-static members) -// -// So, LinkerInitialized object of SynchronizationStorage uses a -// non-trivial constructor, which is called at some point during dynamic -// initialization, and is therefore subject to order of dynamic -// initialization bugs, where get() is called before the object's -// constructor is, resulting in undefined behavior. -// -// Similarly, a LinkerInitialized SynchronizationStorage object has a -// non-trivial destructor, and so its lifetime ends at some point during -// destruction of objects with static storage duration [basic.start.term] -// p4. There is a window where other exit code could call get() after this -// occurs, resulting in undefined behavior. -// -// Combined, these statements imply that LinkerInitialized instances -// of SynchronizationStorage rely on undefined behavior. -// -// However, in practice, the implementation works on all supported -// compilers. Specifically, we rely on: -// -// a) zero-initialization being sufficient to initialize -// LinkerInitialized instances for the purposes of calling -// get(), regardless of when the constructor is called. This is -// because the is_dynamic_ boolean is correctly zero-initialized to -// false. -// -// b) the LinkerInitialized constructor is a NOP, and immaterial to -// even to concurrent calls to get(). -// -// c) the destructor being a NOP for LinkerInitialized objects -// (guaranteed by a check for !is_dynamic_), and so any concurrent and -// subsequent calls to get() functioning as if the destructor were not -// called, by virtue of the instances' storage remaining valid after the -// destructor runs. -// -// d) That a-c apply transitively when SynchronizationStorage is the -// only member of a class allocated in static storage. -// -// Nothing in the language standard guarantees that a-d hold. In practice, -// these hold in all supported compilers. -// -// Future direction: -// -// Ideally, we would simply use std::mutex or a similar class, which when -// allocated statically would support use immediately after static -// initialization up until static storage is reclaimed (i.e. the properties -// we require of all "linker initialized" instances). -// -// Regarding construction in static storage, std::mutex is required to -// provide a constexpr default constructor [thread.mutex.class], which -// ensures the instance's lifetime begins with static initialization -// [basic.start.init], and so is immune to any problems caused by the order -// of dynamic initialization. However, as of this writing Microsoft's -// Visual Studio does not provide a constexpr constructor for std::mutex. -// See -// https://blogs.msdn.microsoft.com/vcblog/2015/06/02/constexpr-complete-for-vs-2015-rtm-c11-compiler-c17-stl/ -// -// Regarding destruction of instances in static storage, [basic.life] does -// say an object ends when storage in which the occupies is released, in -// the case of non-trivial destructor. However, std::mutex is not specified -// to have a trivial destructor. -// -// So, we would need a class with a constexpr default constructor and a -// trivial destructor. Today, we can achieve neither desired property using -// std::mutex directly. -template -class SynchronizationStorage { - public: - // Instances allocated on the heap or on the stack should use the default - // constructor. - SynchronizationStorage() - : destruct_(true), once_() {} - - constexpr explicit SynchronizationStorage(absl::ConstInitType) - : destruct_(false), once_(), space_{{0}} {} - - SynchronizationStorage(SynchronizationStorage&) = delete; - SynchronizationStorage& operator=(SynchronizationStorage&) = delete; - - ~SynchronizationStorage() { - if (destruct_) { - get()->~T(); - } - } - - // Retrieve the object in storage. This is fast and thread safe, but does - // incur the cost of absl::call_once(). - T* get() { - absl::call_once(once_, SynchronizationStorage::Construct, this); - return reinterpret_cast(&space_); - } - - private: - static void Construct(SynchronizationStorage* self) { - new (&self->space_) T(); - } - - // When true, T's destructor is run when this is destructed. - const bool destruct_; - - absl::once_flag once_; - - // An aligned space for the T. - alignas(T) unsigned char space_[sizeof(T)]; -}; - -} // namespace synchronization_internal -ABSL_NAMESPACE_END -} // namespace absl diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 52401fe3..6340bd63 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -72,15 +72,6 @@ #include "absl/synchronization/internal/per_thread_sem.h" #include "absl/time/time.h" -// Decide if we should use the non-production implementation because -// the production implementation hasn't been fully ported yet. -#ifdef ABSL_INTERNAL_USE_NONPROD_MUTEX -#error ABSL_INTERNAL_USE_NONPROD_MUTEX cannot be directly set -#elif defined(ABSL_LOW_LEVEL_ALLOC_MISSING) -#define ABSL_INTERNAL_USE_NONPROD_MUTEX 1 -#include "absl/synchronization/internal/mutex_nonprod.inc" -#endif - namespace absl { ABSL_NAMESPACE_BEGIN @@ -461,15 +452,6 @@ class ABSL_LOCKABLE Mutex { static void InternalAttemptToUseMutexInFatalSignalHandler(); private: -#ifdef ABSL_INTERNAL_USE_NONPROD_MUTEX - friend class CondVar; - - synchronization_internal::MutexImpl *impl() { return impl_.get(); } - - synchronization_internal::SynchronizationStorage< - synchronization_internal::MutexImpl> - impl_; -#else std::atomic mu_; // The Mutex state. // Post()/Wait() versus associated PerThreadSem; in class for required @@ -504,7 +486,6 @@ class ABSL_LOCKABLE Mutex { void Trans(MuHow how); // used for CondVar->Mutex transfer void Fer( base_internal::PerThreadSynch *w); // used for CondVar->Mutex transfer -#endif // Catch the error of writing Mutex when intending MutexLock. Mutex(const volatile Mutex * /*ignored*/) {} // NOLINT(runtime/explicit) @@ -838,17 +819,10 @@ class CondVar { void EnableDebugLog(const char *name); private: -#ifdef ABSL_INTERNAL_USE_NONPROD_MUTEX - synchronization_internal::CondVarImpl *impl() { return impl_.get(); } - synchronization_internal::SynchronizationStorage< - synchronization_internal::CondVarImpl> - impl_; -#else bool WaitCommon(Mutex *mutex, synchronization_internal::KernelTimeout t); void Remove(base_internal::PerThreadSynch *s); void Wakeup(base_internal::PerThreadSynch *w); std::atomic cv_; // Condition variable state. -#endif CondVar(const CondVar&) = delete; CondVar& operator=(const CondVar&) = delete; }; @@ -906,12 +880,6 @@ class ABSL_SCOPED_LOCKABLE ReleasableMutexLock { ReleasableMutexLock& operator=(ReleasableMutexLock&&) = delete; }; -#ifdef ABSL_INTERNAL_USE_NONPROD_MUTEX - -inline constexpr Mutex::Mutex(absl::ConstInitType) : impl_(absl::kConstInit) {} - -#else - inline Mutex::Mutex() : mu_(0) { ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static); } @@ -920,8 +888,6 @@ inline constexpr Mutex::Mutex(absl::ConstInitType) : mu_(0) {} inline CondVar::CondVar() : cv_(0) {} -#endif // ABSL_INTERNAL_USE_NONPROD_MUTEX - // static template bool Condition::CastAndCallMethod(const Condition *c) { diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc index 16fc9058..66d5f2aa 100644 --- a/absl/synchronization/mutex_test.cc +++ b/absl/synchronization/mutex_test.cc @@ -1002,9 +1002,6 @@ TEST(Mutex, AcquireFromCondition) { x.mu0.Unlock(); } -// The deadlock detector is not part of non-prod builds, so do not test it. -#if !defined(ABSL_INTERNAL_USE_NONPROD_MUTEX) - TEST(Mutex, DeadlockDetector) { absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort); @@ -1158,7 +1155,6 @@ TEST(Mutex, DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS { c.Lock(); c.Unlock(); } -#endif // !defined(ABSL_INTERNAL_USE_NONPROD_MUTEX) // -------------------------------------------------------- // Test for timeouts/deadlines on condition waits that are specified using -- cgit v1.2.3 From 92ba53599931fcbe31e7970497cb9e60091434c1 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 7 Jan 2021 06:10:17 -0800 Subject: Export of internal Abseil changes -- e86453648e05d9bf30ff97a68fba8ce5134ee1c9 by Abseil Team : Fix compilation in C with clang on windows with -Wundef flag PiperOrigin-RevId: 350545275 GitOrigin-RevId: e86453648e05d9bf30ff97a68fba8ce5134ee1c9 Change-Id: I029538298ff894d5798b9c6f488af7aa1a3ec2a7 --- absl/base/config.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index 3f7f32b9..c9a06f1d 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -490,7 +490,7 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #endif #ifdef __has_include -#if __has_include() && __cplusplus >= 201703L && \ +#if __has_include() && defined(__cplusplus) && __cplusplus >= 201703L && \ !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE #define ABSL_HAVE_STD_ANY 1 #endif @@ -504,8 +504,8 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #endif #ifdef __has_include -#if __has_include() && __cplusplus >= 201703L && \ - !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE +#if __has_include() && defined(__cplusplus) && \ + __cplusplus >= 201703L && !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE #define ABSL_HAVE_STD_OPTIONAL 1 #endif #endif @@ -518,8 +518,8 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #endif #ifdef __has_include -#if __has_include() && __cplusplus >= 201703L && \ - !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE +#if __has_include() && defined(__cplusplus) && \ + __cplusplus >= 201703L && !ABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE #define ABSL_HAVE_STD_VARIANT 1 #endif #endif @@ -532,7 +532,8 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #endif #ifdef __has_include -#if __has_include() && __cplusplus >= 201703L +#if __has_include() && defined(__cplusplus) && \ + __cplusplus >= 201703L #define ABSL_HAVE_STD_STRING_VIEW 1 #endif #endif @@ -544,8 +545,9 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || // not correctly set by MSVC, so we use `_MSVC_LANG` to check the language // version. // TODO(zhangxy): fix tests before enabling aliasing for `std::any`. -#if defined(_MSC_VER) && _MSC_VER >= 1910 && \ - ((defined(_MSVC_LANG) && _MSVC_LANG > 201402) || __cplusplus > 201402) +#if defined(_MSC_VER) && _MSC_VER >= 1910 && \ + ((defined(_MSVC_LANG) && _MSVC_LANG > 201402) || \ + (defined(__cplusplus) && __cplusplus > 201402)) // #define ABSL_HAVE_STD_ANY 1 #define ABSL_HAVE_STD_OPTIONAL 1 #define ABSL_HAVE_STD_VARIANT 1 -- cgit v1.2.3 From 322ae2420d27fc96d0a8ab1167d7de33671048df Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 12 Jan 2021 07:36:20 -0800 Subject: Export of internal Abseil changes -- 1609589925459c2c0b2a17912c0d65227f709db9 by Abseil Team : Clarify the "Potential Mutex deadlock" reason message. PiperOrigin-RevId: 351367862 -- 88bf28863db2c2d2d48767c3e4dfab6a48bdff79 by Abseil Team : Print CPU number is fault handler. This CL adds code to print CPU number inside the fault handler. This is only supported on Linux. The CPU number is also a hint only. There is no guarantee that it is indeed the CPU on which a fault happened. PiperOrigin-RevId: 351238373 -- 66a9c8e44b5744fec1ca0d7b8db7e1d50772d9a2 by Samuel Benzaquen : Add better error message for ODR violations of flags. PiperOrigin-RevId: 351197423 -- 6efd1efb341563148dd43255aaa4bf959dfd9554 by Chris Kennelly : Assume bitwise builtins are available on GCC. These are long-standing builtins but are not consistently detected by ABSL_HAVE_BUILTIN. PiperOrigin-RevId: 350814036 GitOrigin-RevId: 1609589925459c2c0b2a17912c0d65227f709db9 Change-Id: Ied3fd2f135187f2c316b403fba45f3bbaea54138 --- absl/base/config.h | 9 +++++++ absl/debugging/failure_signal_handler.cc | 36 +++++++++++++++++++-------- absl/debugging/failure_signal_handler_test.cc | 6 +++++ absl/flags/flag.h | 10 +++++--- absl/flags/flag_test.cc | 2 +- absl/flags/internal/flag.h | 5 ++-- absl/flags/internal/registry.h | 2 +- absl/flags/reflection.cc | 23 +++++++++++++---- absl/numeric/bits_test.cc | 8 ++++++ absl/numeric/internal/bits.h | 29 +++++++++++++-------- absl/synchronization/mutex.cc | 4 ++- 11 files changed, 100 insertions(+), 34 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index c9a06f1d..f6ddf0c5 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -379,6 +379,15 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1 #endif +// ABSL_HAVE_SCHED_GETCPU +// +// Checks whether sched_getcpu is available. +#ifdef ABSL_HAVE_SCHED_GETCPU +#error ABSL_HAVE_SCHED_GETCPU cannot be directly set +#elif defined(__linux__) +#define ABSL_HAVE_SCHED_GETCPU 1 +#endif + // ABSL_HAVE_SCHED_YIELD // // Checks whether the platform implements sched_yield(2) as defined in diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc index 5d13bdbb..a9ed6ef9 100644 --- a/absl/debugging/failure_signal_handler.cc +++ b/absl/debugging/failure_signal_handler.cc @@ -21,6 +21,7 @@ #ifdef _WIN32 #include #else +#include #include #endif @@ -219,17 +220,24 @@ static void WriteToStderr(const char* data) { absl::raw_logging_internal::SafeWriteToStderr(data, strlen(data)); } -static void WriteSignalMessage(int signo, void (*writerfn)(const char*)) { - char buf[64]; +static void WriteSignalMessage(int signo, int cpu, + void (*writerfn)(const char*)) { + char buf[96]; + char on_cpu[32] = {0}; + if (cpu != -1) { + snprintf(on_cpu, sizeof(on_cpu), " on cpu %d", cpu); + } const char* const signal_string = debugging_internal::FailureSignalToString(signo); if (signal_string != nullptr && signal_string[0] != '\0') { - snprintf(buf, sizeof(buf), "*** %s received at time=%ld ***\n", + snprintf(buf, sizeof(buf), "*** %s received at time=%ld%s ***\n", signal_string, - static_cast(time(nullptr))); // NOLINT(runtime/int) + static_cast(time(nullptr)), // NOLINT(runtime/int) + on_cpu); } else { - snprintf(buf, sizeof(buf), "*** Signal %d received at time=%ld ***\n", - signo, static_cast(time(nullptr))); // NOLINT(runtime/int) + snprintf(buf, sizeof(buf), "*** Signal %d received at time=%ld%s ***\n", + signo, static_cast(time(nullptr)), // NOLINT(runtime/int) + on_cpu); } writerfn(buf); } @@ -269,10 +277,10 @@ ABSL_ATTRIBUTE_NOINLINE static void WriteStackTrace( // Called by AbslFailureSignalHandler() to write the failure info. It is // called once with writerfn set to WriteToStderr() and then possibly // with writerfn set to the user provided function. -static void WriteFailureInfo(int signo, void* ucontext, +static void WriteFailureInfo(int signo, void* ucontext, int cpu, void (*writerfn)(const char*)) { WriterFnStruct writerfn_struct{writerfn}; - WriteSignalMessage(signo, writerfn); + WriteSignalMessage(signo, cpu, writerfn); WriteStackTrace(ucontext, fsh_options.symbolize_stacktrace, WriterFnWrapper, &writerfn_struct); } @@ -334,6 +342,14 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) { } } + // Increase the chance that the CPU we report was the same CPU on which the + // signal was received by doing this as early as possible, i.e. after + // verifying that this is not a recursive signal handler invocation. + int my_cpu = -1; +#ifdef ABSL_HAVE_SCHED_GETCPU + my_cpu = sched_getcpu(); +#endif + #ifdef ABSL_HAVE_ALARM // Set an alarm to abort the program in case this code hangs or deadlocks. if (fsh_options.alarm_on_failure_secs > 0) { @@ -344,12 +360,12 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) { #endif // First write to stderr. - WriteFailureInfo(signo, ucontext, WriteToStderr); + WriteFailureInfo(signo, ucontext, my_cpu, WriteToStderr); // Riskier code (because it is less likely to be async-signal-safe) // goes after this point. if (fsh_options.writerfn != nullptr) { - WriteFailureInfo(signo, ucontext, fsh_options.writerfn); + WriteFailureInfo(signo, ucontext, my_cpu, fsh_options.writerfn); } if (fsh_options.call_previous_handler) { diff --git a/absl/debugging/failure_signal_handler_test.cc b/absl/debugging/failure_signal_handler_test.cc index d8283b2f..6a62428b 100644 --- a/absl/debugging/failure_signal_handler_test.cc +++ b/absl/debugging/failure_signal_handler_test.cc @@ -122,6 +122,12 @@ TEST_P(FailureSignalHandlerDeathTest, AbslFatalSignalsWithWriterFn) { "*** ", absl::debugging_internal::FailureSignalToString(signo), " received at "))); + // On platforms where it is possible to get the current CPU, the + // CPU number is also logged. Check that it is present in output. +#if defined(__linux__) + EXPECT_THAT(error_line, testing::HasSubstr(" on cpu ")); +#endif + if (absl::debugging_internal::StackTraceWorksForTest()) { std::getline(error_output, error_line); EXPECT_THAT(error_line, StartsWith("PC: ")); diff --git a/absl/flags/flag.h b/absl/flags/flag.h index a9cb2b79..f09580b0 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -301,13 +301,15 @@ ABSL_NAMESPACE_END #if ABSL_FLAGS_STRIP_NAMES #define ABSL_FLAG_IMPL_FLAGNAME(txt) "" #define ABSL_FLAG_IMPL_FILENAME() "" -#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \ - absl::flags_internal::FlagRegistrar(ABSL_FLAG_IMPL_FLAG_PTR(flag)) +#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \ + absl::flags_internal::FlagRegistrar(ABSL_FLAG_IMPL_FLAG_PTR(flag), \ + nullptr) #else #define ABSL_FLAG_IMPL_FLAGNAME(txt) txt #define ABSL_FLAG_IMPL_FILENAME() __FILE__ -#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \ - absl::flags_internal::FlagRegistrar(ABSL_FLAG_IMPL_FLAG_PTR(flag)) +#define ABSL_FLAG_IMPL_REGISTRAR(T, flag) \ + absl::flags_internal::FlagRegistrar(ABSL_FLAG_IMPL_FLAG_PTR(flag), \ + __FILE__) #endif // ABSL_FLAG_IMPL macro definition conditional on ABSL_FLAGS_STRIP_HELP diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc index 72507b99..6912b546 100644 --- a/absl/flags/flag_test.cc +++ b/absl/flags/flag_test.cc @@ -177,7 +177,7 @@ bool TestConstructionFor(const absl::Flag& f1, absl::Flag& f2) { EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Help(), "literal help"); EXPECT_EQ(absl::GetFlagReflectionHandle(f1).Filename(), "file"); - flags::FlagRegistrar(ABSL_FLAG_IMPL_FLAG_PTR(f2)) + flags::FlagRegistrar(ABSL_FLAG_IMPL_FLAG_PTR(f2), nullptr) .OnUpdate(TestCallback); EXPECT_EQ(absl::GetFlagReflectionHandle(f2).Name(), "f2"); diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index 83548143..e6bade0a 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -721,8 +721,9 @@ struct FlagRegistrarEmpty {}; template class FlagRegistrar { public: - explicit FlagRegistrar(Flag& flag) : flag_(flag) { - if (do_register) flags_internal::RegisterCommandLineFlag(flag_.impl_); + explicit FlagRegistrar(Flag& flag, const char* filename) : flag_(flag) { + if (do_register) + flags_internal::RegisterCommandLineFlag(flag_.impl_, filename); } FlagRegistrar OnUpdate(FlagCallbackFunc cb) && { diff --git a/absl/flags/internal/registry.h b/absl/flags/internal/registry.h index a8d9eb9c..4b68c85f 100644 --- a/absl/flags/internal/registry.h +++ b/absl/flags/internal/registry.h @@ -36,7 +36,7 @@ void ForEachFlag(std::function visitor); //----------------------------------------------------------------------------- -bool RegisterCommandLineFlag(CommandLineFlag&); +bool RegisterCommandLineFlag(CommandLineFlag&, const char* filename); void FinalizeRegistry(); diff --git a/absl/flags/reflection.cc b/absl/flags/reflection.cc index c976d467..0c761101 100644 --- a/absl/flags/reflection.cc +++ b/absl/flags/reflection.cc @@ -50,7 +50,7 @@ class FlagRegistry { ~FlagRegistry() = default; // Store a flag in this registry. Takes ownership of *flag. - void RegisterFlag(CommandLineFlag& flag); + void RegisterFlag(CommandLineFlag& flag, const char* filename); void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(lock_) { lock_.Lock(); } void Unlock() ABSL_UNLOCK_FUNCTION(lock_) { lock_.Unlock(); } @@ -110,7 +110,20 @@ CommandLineFlag* FlagRegistry::FindFlag(absl::string_view name) { return it != flags_.end() ? it->second : nullptr; } -void FlagRegistry::RegisterFlag(CommandLineFlag& flag) { +void FlagRegistry::RegisterFlag(CommandLineFlag& flag, const char* filename) { + if (filename != nullptr && + flag.Filename() != GetUsageConfig().normalize_filename(filename)) { + flags_internal::ReportUsageError( + absl::StrCat( + "Inconsistency between flag object and registration for flag '", + flag.Name(), + "', likely due to duplicate flags or an ODR violation. Relevant " + "files: ", + flag.Filename(), " and ", filename), + true); + std::exit(1); + } + FlagRegistryLock registry_lock(*this); std::pair ins = @@ -175,8 +188,8 @@ void ForEachFlag(std::function visitor) { // -------------------------------------------------------------------- -bool RegisterCommandLineFlag(CommandLineFlag& flag) { - FlagRegistry::GlobalRegistry().RegisterFlag(flag); +bool RegisterCommandLineFlag(CommandLineFlag& flag, const char* filename) { + FlagRegistry::GlobalRegistry().RegisterFlag(flag, filename); return true; } @@ -266,7 +279,7 @@ void Retire(const char* name, FlagFastTypeId type_id, char* buf) { static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment, ""); auto* flag = ::new (static_cast(buf)) flags_internal::RetiredFlagObj(name, type_id); - FlagRegistry::GlobalRegistry().RegisterFlag(*flag); + FlagRegistry::GlobalRegistry().RegisterFlag(*flag, nullptr); } // -------------------------------------------------------------------- diff --git a/absl/numeric/bits_test.cc b/absl/numeric/bits_test.cc index 8bf7bc9f..7c942aae 100644 --- a/absl/numeric/bits_test.cc +++ b/absl/numeric/bits_test.cc @@ -560,6 +560,14 @@ TEST(IntegralPowersOfTwo, Width) { } } +// On GCC and Clang, anticiapte that implementations will be constexpr +#if defined(__GNUC__) +static_assert(ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT, + "popcount should be constexpr"); +static_assert(ABSL_INTERNAL_HAS_CONSTEXPR_CLZ, "clz should be constexpr"); +static_assert(ABSL_INTERNAL_HAS_CONSTEXPR_CTZ, "ctz should be constexpr"); +#endif + } // namespace ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/numeric/internal/bits.h b/absl/numeric/internal/bits.h index af45700f..e51941d7 100644 --- a/absl/numeric/internal/bits.h +++ b/absl/numeric/internal/bits.h @@ -28,8 +28,15 @@ #include "absl/base/attributes.h" #include "absl/base/config.h" -#if ABSL_HAVE_BUILTIN(__builtin_popcountl) && \ - ABSL_HAVE_BUILTIN(__builtin_popcountll) +#if defined(__GNUC__) && !defined(__clang__) +// GCC +#define ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(x) 1 +#else +#define ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(x) ABSL_HAVE_BUILTIN(x) +#endif + +#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountl) && \ + ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountll) #define ABSL_INTERNAL_CONSTEXPR_POPCOUNT constexpr #define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 1 #else @@ -37,7 +44,8 @@ #define ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT 0 #endif -#if ABSL_HAVE_BUILTIN(__builtin_clz) && ABSL_HAVE_BUILTIN(__builtin_clzll) +#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clz) && \ + ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clzll) #define ABSL_INTERNAL_CONSTEXPR_CLZ constexpr #define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 1 #else @@ -45,7 +53,8 @@ #define ABSL_INTERNAL_HAS_CONSTEXPR_CLZ 0 #endif -#if ABSL_HAVE_BUILTIN(__builtin_ctz) && ABSL_HAVE_BUILTIN(__builtin_ctzll) +#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctz) && \ + ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctzll) #define ABSL_INTERNAL_CONSTEXPR_CTZ constexpr #define ABSL_INTERNAL_HAS_CONSTEXPR_CTZ 1 #else @@ -85,7 +94,7 @@ ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateLeft( ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int Popcount32(uint32_t x) noexcept { -#if ABSL_HAVE_BUILTIN(__builtin_popcount) +#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcount) static_assert(sizeof(unsigned int) == sizeof(x), "__builtin_popcount does not take 32-bit arg"); return __builtin_popcount(x); @@ -98,7 +107,7 @@ Popcount32(uint32_t x) noexcept { ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int Popcount64(uint64_t x) noexcept { -#if ABSL_HAVE_BUILTIN(__builtin_popcountll) +#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_popcountll) static_assert(sizeof(unsigned long long) == sizeof(x), // NOLINT(runtime/int) "__builtin_popcount does not take 64-bit arg"); return __builtin_popcountll(x); @@ -122,7 +131,7 @@ Popcount(T x) noexcept { ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int CountLeadingZeroes32(uint32_t x) { -#if ABSL_HAVE_BUILTIN(__builtin_clz) +#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clz) // Use __builtin_clz, which uses the following instructions: // x86: bsr, lzcnt // ARM64: clz @@ -169,7 +178,7 @@ CountLeadingZeroes16(uint16_t x) { ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CLZ inline int CountLeadingZeroes64(uint64_t x) { -#if ABSL_HAVE_BUILTIN(__builtin_clzll) +#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_clzll) // Use __builtin_clzll, which uses the following instructions: // x86: bsr, lzcnt // ARM64: clz @@ -240,7 +249,7 @@ CountLeadingZeroes(T x) { ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int CountTrailingZeroesNonzero32(uint32_t x) { -#if ABSL_HAVE_BUILTIN(__builtin_ctz) +#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctz) static_assert(sizeof(unsigned int) == sizeof(x), "__builtin_ctz does not take 32-bit arg"); return __builtin_ctz(x); @@ -262,7 +271,7 @@ CountTrailingZeroesNonzero32(uint32_t x) { ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_CTZ inline int CountTrailingZeroesNonzero64(uint64_t x) { -#if ABSL_HAVE_BUILTIN(__builtin_ctzll) +#if ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(__builtin_ctzll) static_assert(sizeof(unsigned long long) == sizeof(x), // NOLINT(runtime/int) "__builtin_ctzll does not take 64-bit arg"); return __builtin_ctzll(x); diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index d2468ce5..7e66a7d0 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc @@ -1372,7 +1372,9 @@ static GraphId DeadlockCheck(Mutex *mu) { len += static_cast(strlen(&b->buf[len])); } } - ABSL_RAW_LOG(ERROR, "Acquiring %p Mutexes held: %s", + ABSL_RAW_LOG(ERROR, + "Acquiring absl::Mutex %p while holding %s; a cycle in the " + "historical lock ordering graph has been observed", static_cast(mu), b->buf); ABSL_RAW_LOG(ERROR, "Cycle: "); int path_len = deadlock_graph->FindPath( -- cgit v1.2.3 From a9a49560208484f1f99efdde889da6147e8722fe Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 29 Jan 2021 12:09:30 -0800 Subject: Export of internal Abseil changes -- c68f1886f5e8fd90eb0c2d2e68feaf00a7cdacda by CJ Johnson : Introduce absl::Cleanup to the OSS repo PiperOrigin-RevId: 354583156 -- 17030cf388e10f7eb959e3e566326d1072ce392e by Abseil Team : Internal change only PiperOrigin-RevId: 354574953 -- e979d7236d4f3252e79ddda6739b67a9a326bf6d by CJ Johnson : Internal change PiperOrigin-RevId: 354545297 -- 7ea02b3783f7f49ef97d86a8f6580a19cc57df14 by Abseil Team : Pre-allocate memory for vectors where the size is known. PiperOrigin-RevId: 354344576 -- 9246c7cb11f1d6444f79ebe25acc69a8a9b870e0 by Matt Kulukundis : Add support for Elbrus 2000 (e2k) Import of https://github.com/abseil/abseil-cpp/pull/889 PiperOrigin-RevId: 354344013 -- 0fc93d359cc1fb307552e917b37b7b2e7eed822f by Abseil Team : Integrate CordRepRing logic into cord (but do not enable it) PiperOrigin-RevId: 354312238 -- eda05622f7da71466723acb33403f783529df24b by Abseil Team : Protect ignore diagnostic with "__has_warning". PiperOrigin-RevId: 354112334 -- 47716c5d8fb10efa4fdd801d28bac414c6f8ec32 by Abseil Team : Rearrange InlinedVector copy constructor and destructor to treat a few special cases inline and then tail-call a non-inlined routine for the rest. In particular, we optimize for empty vectors in both cases. Added a couple of benchmarks that copy either an InlVec or an InlVec>. Speed difference: ``` BM_CopyTrivial/0 0.92ns +- 0% 0.47ns +- 0% -48.91% (p=0.000 n=11+12) BM_CopyTrivial/1 0.92ns +- 0% 1.15ns +- 0% +25.00% (p=0.000 n=10+9) BM_CopyTrivial/8 8.57ns +- 0% 10.72ns +- 1% +25.16% (p=0.000 n=10+12) BM_CopyNonTrivial/0 3.21ns +- 0% 0.70ns +- 0% -78.23% (p=0.000 n=12+10) BM_CopyNonTrivial/1 5.88ns +- 1% 5.51ns +- 0% -6.28% (p=0.000 n=10+8) BM_CopyNonTrivial/8 21.5ns +- 1% 15.2ns +- 2% -29.23% (p=0.000 n=12+12) ``` Note: the slowdowns are a few cycles which is expected given the procedure call added in that case. We decided this is a good tradeoff given the code size reductions and the more significant speedups for empty vectors. Size difference (as measured by nm): ``` BM_CopyTrivial from 1048 bytes to 326 bytes. BM_CopyNonTrivial from 749 bytes to 470 bytes. ``` Code size for a large binary drops by ~500KB (from 349415719 to 348906015 348906191). All of the benchmarks that showed a significant difference: Ones that improve with this CL: ``` BM_CopyNonTrivial/0 3.21ns +- 0% 0.70ns +- 0% -78.23% (p=0.000 n=12+10) BM_InlinedVectorFillString/0 0.93ns +- 0% 0.24ns +- 0% -74.19% (p=0.000 n=12+10) BM_InlinedVectorAssignments/1 10.5ns +- 0% 4.1ns +- 0% -60.64% (p=0.000 n=11+10) BM_InlinedVectorAssignments/2 10.7ns +- 0% 4.4ns +- 0% -59.08% (p=0.000 n=11+11) BM_CopyTrivial/0 0.92ns +- 0% 0.47ns +- 0% -48.91% (p=0.000 n=11+12) BM_CopyNonTrivial/8 21.5ns +- 1% 15.2ns +- 2% -29.23% (p=0.000 n=12+12) BM_StdVectorEmpty 0.47ns +- 1% 0.35ns +- 0% -24.73% (p=0.000 n=12+12) BM_StdVectorSize 0.46ns +- 2% 0.35ns +- 0% -24.32% (p=0.000 n=12+12) BM_SwapElements/0 3.44ns +- 0% 2.76ns +- 1% -19.83% (p=0.000 n=11+11) BM_InlinedVectorFillRange/256 20.7ns +- 1% 17.8ns +- 0% -14.08% (p=0.000 n=12+9) BM_CopyNonTrivial/1 5.88ns +- 1% 5.51ns +- 0% -6.28% (p=0.000 n=10+8) BM_SwapElements/1 4.19ns +- 0% 3.95ns +- 1% -5.63% (p=0.000 n=11+12) BM_SwapElements/1 4.18ns +- 0% 3.99ns +- 0% -4.70% (p=0.000 n=9+11) BM_SwapElements/0 2.41ns +- 0% 2.31ns +- 0% -4.45% (p=0.000 n=12+12) BM_InlinedVectorFillRange/64 8.25ns +- 0% 8.04ns +- 0% -2.51% (p=0.000 n=12+11) BM_SwapElements/1 82.4ns +- 0% 81.5ns +- 0% -1.06% (p=0.000 n=12+12) ``` Ones that get worse with this CL: ``` BM_CopyTrivial/1 0.92ns +- 0% 1.15ns +- 0% +25.00% (p=0.000 n=10+9) BM_CopyTrivial/8 8.57ns +- 0% 10.72ns +- 1% +25.16% (p=0.000 n=10+12) BM_SwapElements/512 1.48ns +- 1% 1.66ns +- 1% +11.88% (p=0.000 n=12+12) BM_InlinedVectorFillString/1 11.5ns +- 0% 12.8ns +- 1% +11.62% (p=0.000 n=12+11) BM_SwapElements/64 1.48ns +- 2% 1.66ns +- 1% +11.66% (p=0.000 n=12+11) BM_SwapElements/1k 1.48ns +- 1% 1.65ns +- 2% +11.32% (p=0.000 n=12+12) BM_SwapElements/512 1.48ns +- 2% 1.58ns +- 4% +6.62% (p=0.000 n=11+12) BM_SwapElements/1k 1.49ns +- 2% 1.58ns +- 3% +6.05% (p=0.000 n=12+12) BM_SwapElements/64 1.48ns +- 2% 1.57ns +- 4% +6.04% (p=0.000 n=11+12) BM_InlinedVectorFillRange/1 4.81ns +- 0% 5.05ns +- 0% +4.83% (p=0.000 n=11+11) BM_InlinedVectorFillString/8 79.4ns +- 1% 83.1ns +- 1% +4.64% (p=0.000 n=10+12) BM_StdVectorFillString/1 16.3ns +- 0% 16.6ns +- 0% +2.13% (p=0.000 n=11+8) ``` PiperOrigin-RevId: 353906786 -- 8e26518b3cec9c598e5e9573c46c3bd1b03a67ef by Abseil Team : Internal change PiperOrigin-RevId: 353737330 -- f206ae0983e58c9904ed8b8f05f9caf564a446be by Matt Kulukundis : Import of CCTZ from GitHub. PiperOrigin-RevId: 353682256 GitOrigin-RevId: c68f1886f5e8fd90eb0c2d2e68feaf00a7cdacda Change-Id: I5790c1036c4f543c701d1039848fabf7ae881ad8 --- CMake/AbseilDll.cmake | 2 + README.md | 3 + absl/base/config.h | 9 + absl/base/spinlock_test_common.cc | 1 + absl/cleanup/BUILD.bazel | 66 ++++++ absl/cleanup/CMakeLists.txt | 55 +++++ absl/cleanup/cleanup.h | 129 +++++++++++ absl/cleanup/cleanup_test.cc | 240 +++++++++++++++++++++ absl/cleanup/internal/cleanup.h | 77 +++++++ absl/container/inlined_vector.h | 8 +- absl/container/inlined_vector_benchmark.cc | 22 ++ absl/container/internal/inlined_vector.h | 66 +++++- absl/status/status.cc | 16 +- absl/status/status.h | 9 +- absl/strings/cord.cc | 141 +++++++++++- absl/strings/cord.h | 43 +++- absl/strings/cord_test.cc | 6 +- absl/strings/internal/cord_rep_flat.h | 7 +- absl/strings/internal/cord_rep_ring.cc | 2 + absl/strings/internal/cord_rep_ring.h | 4 +- absl/time/internal/cctz/testdata/version | 2 +- .../internal/cctz/testdata/zoneinfo/Africa/Juba | Bin 449 -> 458 bytes 22 files changed, 876 insertions(+), 32 deletions(-) create mode 100644 absl/cleanup/BUILD.bazel create mode 100644 absl/cleanup/CMakeLists.txt create mode 100644 absl/cleanup/cleanup.h create mode 100644 absl/cleanup/cleanup_test.cc create mode 100644 absl/cleanup/internal/cleanup.h (limited to 'absl/base/config.h') diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake index b8c38d68..47707dfd 100644 --- a/CMake/AbseilDll.cmake +++ b/CMake/AbseilDll.cmake @@ -60,6 +60,8 @@ set(ABSL_INTERNAL_DLL_FILES "base/policy_checks.h" "base/port.h" "base/thread_annotations.h" + "cleanup/cleanup.h" + "cleanup/internal/cleanup.h" "container/btree_map.h" "container/btree_set.h" "container/fixed_array.h" diff --git a/README.md b/README.md index 76f1d1e1..264c4b3f 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,9 @@ Abseil contains the following C++ library components: * [`algorithm`](absl/algorithm/)
The `algorithm` library contains additions to the C++ `` library and container-based versions of such algorithms. +* [`cleanup`](absl/cleanup/) +
The `cleanup` library contains the control-flow-construct-like type + `absl::Cleanup` which is used for executing a callback on scope exit. * [`container`](absl/container/)
The `container` library contains additional STL-style containers, including Abseil's unordered "Swiss table" containers. diff --git a/absl/base/config.h b/absl/base/config.h index f6ddf0c5..3d6aa178 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -722,4 +722,13 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_HAVE_ADDRESS_SANITIZER 1 #endif +// ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION +// +// Class template argument deduction is a language feature added in C++17. +#ifdef ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION +#error "ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION cannot be directly set." +#elif defined(__cpp_deduction_guides) +#define ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1 +#endif + #endif // ABSL_BASE_CONFIG_H_ diff --git a/absl/base/spinlock_test_common.cc b/absl/base/spinlock_test_common.cc index dee266e4..2b572c5b 100644 --- a/absl/base/spinlock_test_common.cc +++ b/absl/base/spinlock_test_common.cc @@ -92,6 +92,7 @@ static void TestFunction(int thread_salt, SpinLock* spinlock) { static void ThreadedTest(SpinLock* spinlock) { std::vector threads; + threads.reserve(kNumThreads); for (int i = 0; i < kNumThreads; ++i) { threads.push_back(std::thread(TestFunction, i, spinlock)); } diff --git a/absl/cleanup/BUILD.bazel b/absl/cleanup/BUILD.bazel new file mode 100644 index 00000000..5cca898f --- /dev/null +++ b/absl/cleanup/BUILD.bazel @@ -0,0 +1,66 @@ +# Copyright 2021 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. + +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") +load( + "//absl:copts/configure_copts.bzl", + "ABSL_DEFAULT_COPTS", + "ABSL_DEFAULT_LINKOPTS", + "ABSL_TEST_COPTS", +) + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +cc_library( + name = "cleanup_internal", + hdrs = ["internal/cleanup.h"], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + "//absl/base:base_internal", + "//absl/base:core_headers", + "//absl/utility", + ], +) + +cc_library( + name = "cleanup", + hdrs = [ + "cleanup.h", + ], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":cleanup_internal", + "//absl/base:config", + "//absl/base:core_headers", + ], +) + +cc_test( + name = "cleanup_test", + size = "small", + srcs = [ + "cleanup_test.cc", + ], + copts = ABSL_TEST_COPTS, + deps = [ + ":cleanup", + "//absl/base:config", + "//absl/utility", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/absl/cleanup/CMakeLists.txt b/absl/cleanup/CMakeLists.txt new file mode 100644 index 00000000..a2dd78a8 --- /dev/null +++ b/absl/cleanup/CMakeLists.txt @@ -0,0 +1,55 @@ +# Copyright 2021 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. + +absl_cc_library( + NAME + cleanup_internal + HDRS + "internal/cleanup.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::base_internal + absl::core_headers + absl::utility + PUBLIC +) + +absl_cc_library( + NAME + cleanup + HDRS + "cleanup.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::cleanup_internal + absl::config + absl::core_headers + PUBLIC +) + +absl_cc_test( + NAME + cleanup_test + SRCS + "cleanup_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::cleanup + absl::config + absl::utility + gmock_main +) diff --git a/absl/cleanup/cleanup.h b/absl/cleanup/cleanup.h new file mode 100644 index 00000000..eba04b33 --- /dev/null +++ b/absl/cleanup/cleanup.h @@ -0,0 +1,129 @@ +// Copyright 2021 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. +// +// ----------------------------------------------------------------------------- +// File: cleanup.h +// ----------------------------------------------------------------------------- +// +// `absl::Cleanup` implements the scope guard idiom, invoking `operator()() &&` +// on the callback it was constructed with, on scope exit. +// +// Example: +// +// ``` +// void CopyGoodData(const char* input_path, const char* output_path) { +// FILE* in_file = fopen(input_path, "r"); +// FILE* out_file = fopen(output_path, "w"); +// if (in_file == nullptr || out_file == nullptr) return; +// +// // C++17 style using class template argument deduction +// absl::Cleanup in_closer = [&in_file] { fclose(in_file); }; +// +// // C++11 style using the factory function +// auto out_closer = absl::MakeCleanup([&out_file] { fclose(out_file); }); +// +// // `fclose` will be called on all exit paths by the cleanup instances +// +// Data data; +// while (ReadData(in_file, &data)) { +// if (data.IsBad()) { +// LOG(ERROR) << "Found bad data."; +// return; // `in_closer` and `out_closer` will call their callbacks +// } +// SaveData(out_file, &data); +// } +// return; // `in_closer` and `out_closer` will call their callbacks +// } +// ``` +// +// `std::move(cleanup).Invoke()` will execute the callback early, before +// destruction, and prevent the callback from executing in the destructor. +// +// Alternatively, `std::move(cleanup).Cancel()` will prevent the callback from +// ever executing at all. +// +// Once a cleanup object has been `std::move(...)`-ed, it may not be used again. + +#ifndef ABSL_CLEANUP_CLEANUP_H_ +#define ABSL_CLEANUP_CLEANUP_H_ + +#include + +#include "absl/base/config.h" +#include "absl/base/macros.h" +#include "absl/cleanup/internal/cleanup.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +template +class ABSL_MUST_USE_RESULT Cleanup { + static_assert(cleanup_internal::WasDeduced(), + "Explicit template parameters are not supported."); + + static_assert(cleanup_internal::ReturnsVoid(), + "Callbacks that return values are not supported."); + + public: + Cleanup(Callback callback) : storage_(std::move(callback)) {} // NOLINT + + Cleanup(Cleanup&& other) : storage_(std::move(other.storage_)) {} + + void Cancel() && { + ABSL_HARDENING_ASSERT(storage_.IsCallbackEngaged()); + storage_.DisengageCallback(); + } + + void Invoke() && { + ABSL_HARDENING_ASSERT(storage_.IsCallbackEngaged()); + storage_.DisengageCallback(); + storage_.InvokeCallback(); + } + + ~Cleanup() { + if (storage_.IsCallbackEngaged()) { + storage_.InvokeCallback(); + } + } + + private: + cleanup_internal::Storage storage_; +}; + +// `auto c = absl::MakeCleanup(/* callback */);` +// +// C++11 type deduction API for creating an instance of `absl::Cleanup`. +template +absl::Cleanup MakeCleanup(Callback callback) { + static_assert(cleanup_internal::WasDeduced(), + "Explicit template parameters are not supported."); + + static_assert(cleanup_internal::ReturnsVoid(), + "Callbacks that return values are not supported."); + + return {std::move(callback)}; +} + +// `absl::Cleanup c = /* callback */;` +// +// C++17 type deduction API for creating an instance of `absl::Cleanup`. +#if defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) +template +Cleanup(Callback callback) -> Cleanup; +#endif // defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_CLEANUP_CLEANUP_H_ diff --git a/absl/cleanup/cleanup_test.cc b/absl/cleanup/cleanup_test.cc new file mode 100644 index 00000000..34e3bfad --- /dev/null +++ b/absl/cleanup/cleanup_test.cc @@ -0,0 +1,240 @@ +// Copyright 2021 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. + +#include "absl/cleanup/cleanup.h" + +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/base/config.h" +#include "absl/utility/utility.h" + +namespace { + +using Tag = absl::cleanup_internal::Tag; + +template +void AssertSameType() { + static_assert(std::is_same::value, ""); +} + +struct IdentityFactory { + template + static Callback AsCallback(Callback callback) { + return Callback(std::move(callback)); + } +}; + +// `FunctorClass` is a type used for testing `absl::Cleanup`. It is intended to +// represent users that make their own move-only callback types outside of +// `std::function` and lambda literals. +class FunctorClass { + using Callback = std::function; + + public: + explicit FunctorClass(Callback callback) : callback_(std::move(callback)) {} + + FunctorClass(FunctorClass&& other) + : callback_(absl::exchange(other.callback_, Callback())) {} + + FunctorClass(const FunctorClass&) = delete; + + FunctorClass& operator=(const FunctorClass&) = delete; + + FunctorClass& operator=(FunctorClass&&) = delete; + + void operator()() const& = delete; + + void operator()() && { + ASSERT_TRUE(callback_); + callback_(); + callback_ = nullptr; + } + + private: + Callback callback_; +}; + +struct FunctorClassFactory { + template + static FunctorClass AsCallback(Callback callback) { + return FunctorClass(std::move(callback)); + } +}; + +struct StdFunctionFactory { + template + static std::function AsCallback(Callback callback) { + return std::function(std::move(callback)); + } +}; + +using CleanupTestParams = + ::testing::Types; +template +struct CleanupTest : public ::testing::Test {}; +TYPED_TEST_SUITE(CleanupTest, CleanupTestParams); + +bool function_pointer_called = false; +void FunctionPointerFunction() { function_pointer_called = true; } + +TYPED_TEST(CleanupTest, FactoryProducesCorrectType) { + { + auto callback = TypeParam::AsCallback([] {}); + auto cleanup = absl::MakeCleanup(std::move(callback)); + + AssertSameType, decltype(cleanup)>(); + } + + { + auto cleanup = absl::MakeCleanup(&FunctionPointerFunction); + + AssertSameType, decltype(cleanup)>(); + } + + { + auto cleanup = absl::MakeCleanup(FunctionPointerFunction); + + AssertSameType, decltype(cleanup)>(); + } +} + +#if defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) +TYPED_TEST(CleanupTest, CTADProducesCorrectType) { + { + auto callback = TypeParam::AsCallback([] {}); + absl::Cleanup cleanup = std::move(callback); + + AssertSameType, decltype(cleanup)>(); + } + + { + absl::Cleanup cleanup = &FunctionPointerFunction; + + AssertSameType, decltype(cleanup)>(); + } + + { + absl::Cleanup cleanup = FunctionPointerFunction; + + AssertSameType, decltype(cleanup)>(); + } +} + +TYPED_TEST(CleanupTest, FactoryAndCTADProduceSameType) { + { + auto callback = IdentityFactory::AsCallback([] {}); + auto factory_cleanup = absl::MakeCleanup(callback); + absl::Cleanup deduction_cleanup = callback; + + AssertSameType(); + } + + { + auto factory_cleanup = + absl::MakeCleanup(FunctorClassFactory::AsCallback([] {})); + absl::Cleanup deduction_cleanup = FunctorClassFactory::AsCallback([] {}); + + AssertSameType(); + } + + { + auto factory_cleanup = + absl::MakeCleanup(StdFunctionFactory::AsCallback([] {})); + absl::Cleanup deduction_cleanup = StdFunctionFactory::AsCallback([] {}); + + AssertSameType(); + } + + { + auto factory_cleanup = absl::MakeCleanup(&FunctionPointerFunction); + absl::Cleanup deduction_cleanup = &FunctionPointerFunction; + + AssertSameType(); + } + + { + auto factory_cleanup = absl::MakeCleanup(FunctionPointerFunction); + absl::Cleanup deduction_cleanup = FunctionPointerFunction; + + AssertSameType(); + } +} +#endif // defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) + +TYPED_TEST(CleanupTest, BasicUsage) { + bool called = false; + + { + EXPECT_FALSE(called); + + auto cleanup = + absl::MakeCleanup(TypeParam::AsCallback([&called] { called = true; })); + + EXPECT_FALSE(called); + } + + EXPECT_TRUE(called); +} + +TYPED_TEST(CleanupTest, BasicUsageWithFunctionPointer) { + function_pointer_called = false; + + { + EXPECT_FALSE(function_pointer_called); + + auto cleanup = + absl::MakeCleanup(TypeParam::AsCallback(&FunctionPointerFunction)); + + EXPECT_FALSE(function_pointer_called); + } + + EXPECT_TRUE(function_pointer_called); +} + +TYPED_TEST(CleanupTest, Cancel) { + bool called = false; + + { + EXPECT_FALSE(called); + + auto cleanup = + absl::MakeCleanup(TypeParam::AsCallback([&called] { called = true; })); + std::move(cleanup).Cancel(); + + EXPECT_FALSE(called); + } + + EXPECT_FALSE(called); +} + +TYPED_TEST(CleanupTest, Invoke) { + bool called = false; + + { + EXPECT_FALSE(called); + + auto cleanup = + absl::MakeCleanup(TypeParam::AsCallback([&called] { called = true; })); + std::move(cleanup).Invoke(); + + EXPECT_TRUE(called); + } + + EXPECT_TRUE(called); +} + +} // namespace diff --git a/absl/cleanup/internal/cleanup.h b/absl/cleanup/internal/cleanup.h new file mode 100644 index 00000000..a126ff30 --- /dev/null +++ b/absl/cleanup/internal/cleanup.h @@ -0,0 +1,77 @@ +// Copyright 2021 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. + +#ifndef ABSL_CLEANUP_INTERNAL_CLEANUP_H_ +#define ABSL_CLEANUP_INTERNAL_CLEANUP_H_ + +#include +#include + +#include "absl/base/internal/invoke.h" +#include "absl/base/thread_annotations.h" +#include "absl/utility/utility.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +namespace cleanup_internal { + +struct Tag {}; + +template +constexpr bool WasDeduced() { + return (std::is_same::value) && + (sizeof...(Args) == 0); +} + +template +constexpr bool ReturnsVoid() { + return (std::is_same, void>::value); +} + +template +class Storage { + public: + explicit Storage(Callback callback) + : engaged_(true), callback_(std::move(callback)) {} + + Storage(Storage&& other) + : engaged_(absl::exchange(other.engaged_, false)), + callback_(std::move(other.callback_)) {} + + Storage(const Storage& other) = delete; + + Storage& operator=(Storage&& other) = delete; + + Storage& operator=(const Storage& other) = delete; + + bool IsCallbackEngaged() const { return engaged_; } + + void DisengageCallback() { engaged_ = false; } + + void InvokeCallback() ABSL_NO_THREAD_SAFETY_ANALYSIS { + std::move(callback_)(); + } + + private: + bool engaged_; + Callback callback_; +}; + +} // namespace cleanup_internal + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_CLEANUP_INTERNAL_CLEANUP_H_ diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index 90bb96e8..7c182342 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -167,11 +167,13 @@ class InlinedVector { // Creates an inlined vector by copying the contents of `other` using `alloc`. InlinedVector(const InlinedVector& other, const allocator_type& alloc) : storage_(alloc) { - if (IsMemcpyOk::value && !other.storage_.GetIsAllocated()) { + if (other.empty()) { + // Empty; nothing to do. + } else if (IsMemcpyOk::value && !other.storage_.GetIsAllocated()) { + // Memcpy-able and do not need allocation. storage_.MemcpyFrom(other.storage_); } else { - storage_.Initialize(IteratorValueAdapter(other.data()), - other.size()); + storage_.InitFrom(other.storage_); } } diff --git a/absl/container/inlined_vector_benchmark.cc b/absl/container/inlined_vector_benchmark.cc index b8dafe93..e256fad6 100644 --- a/absl/container/inlined_vector_benchmark.cc +++ b/absl/container/inlined_vector_benchmark.cc @@ -534,6 +534,28 @@ void BM_ConstructFromMove(benchmark::State& state) { ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromMove, TrivialType); ABSL_INTERNAL_BENCHMARK_ONE_SIZE(BM_ConstructFromMove, NontrivialType); +// Measure cost of copy-constructor+destructor. +void BM_CopyTrivial(benchmark::State& state) { + const int n = state.range(0); + InlVec src(n); + for (auto s : state) { + InlVec copy(src); + benchmark::DoNotOptimize(copy); + } +} +BENCHMARK(BM_CopyTrivial)->Arg(0)->Arg(1)->Arg(kLargeSize); + +// Measure cost of copy-constructor+destructor. +void BM_CopyNonTrivial(benchmark::State& state) { + const int n = state.range(0); + InlVec> src(n); + for (auto s : state) { + InlVec> copy(src); + benchmark::DoNotOptimize(copy); + } +} +BENCHMARK(BM_CopyNonTrivial)->Arg(0)->Arg(1)->Arg(kLargeSize); + template void BM_AssignSizeRef(benchmark::State& state) { auto size = ToSize; diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h index 120849cd..b8aec45b 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h @@ -81,6 +81,23 @@ void DestroyElements(AllocatorType* alloc_ptr, Pointer destroy_first, } } +// If kUseMemcpy is true, memcpy(dst, src, n); else do nothing. +// Useful to avoid compiler warnings when memcpy() is used for T values +// that are not trivially copyable in non-reachable code. +template +inline void MemcpyIfAllowed(void* dst, const void* src, size_t n); + +// memcpy when allowed. +template <> +inline void MemcpyIfAllowed(void* dst, const void* src, size_t n) { + memcpy(dst, src, n); +} + +// Do nothing for types that are not memcpy-able. This function is only +// called from non-reachable branches. +template <> +inline void MemcpyIfAllowed(void*, const void*, size_t) {} + template void ConstructElements(AllocatorType* alloc_ptr, Pointer construct_first, @@ -310,9 +327,14 @@ class Storage { : metadata_(alloc, /* size and is_allocated */ 0) {} ~Storage() { - pointer data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData(); - inlined_vector_internal::DestroyElements(GetAllocPtr(), data, GetSize()); - DeallocateIfAllocated(); + if (GetSizeAndIsAllocated() == 0) { + // Empty and not allocated; nothing to do. + } else if (IsMemcpyOk::value) { + // No destructors need to be run; just deallocate if necessary. + DeallocateIfAllocated(); + } else { + DestroyContents(); + } } // --------------------------------------------------------------------------- @@ -370,6 +392,8 @@ class Storage { // Storage Member Mutators // --------------------------------------------------------------------------- + ABSL_ATTRIBUTE_NOINLINE void InitFrom(const Storage& other); + template void Initialize(ValueAdapter values, size_type new_size); @@ -452,6 +476,8 @@ class Storage { } private: + ABSL_ATTRIBUTE_NOINLINE void DestroyContents(); + using Metadata = container_internal::CompressedTuple; @@ -476,6 +502,40 @@ class Storage { Data data_; }; +template +void Storage::DestroyContents() { + pointer data = GetIsAllocated() ? GetAllocatedData() : GetInlinedData(); + inlined_vector_internal::DestroyElements(GetAllocPtr(), data, GetSize()); + DeallocateIfAllocated(); +} + +template +void Storage::InitFrom(const Storage& other) { + const auto n = other.GetSize(); + assert(n > 0); // Empty sources handled handled in caller. + const_pointer src; + pointer dst; + if (!other.GetIsAllocated()) { + dst = GetInlinedData(); + src = other.GetInlinedData(); + } else { + // Because this is only called from the `InlinedVector` constructors, it's + // safe to take on the allocation with size `0`. If `ConstructElements(...)` + // throws, deallocation will be automatically handled by `~Storage()`. + size_type new_capacity = ComputeCapacity(GetInlinedCapacity(), n); + dst = AllocatorTraits::allocate(*GetAllocPtr(), new_capacity); + SetAllocatedData(dst, new_capacity); + src = other.GetAllocatedData(); + } + if (IsMemcpyOk::value) { + MemcpyIfAllowed(dst, src, sizeof(dst[0]) * n); + } else { + auto values = IteratorValueAdapter(src); + inlined_vector_internal::ConstructElements(GetAllocPtr(), dst, &values, n); + } + GetSizeAndIsAllocated() = other.GetSizeAndIsAllocated(); +} + template template auto Storage::Initialize(ValueAdapter values, size_type new_size) diff --git a/absl/status/status.cc b/absl/status/status.cc index c71de846..7962bb9e 100644 --- a/absl/status/status.cc +++ b/absl/status/status.cc @@ -207,10 +207,12 @@ void Status::UnrefNonInlined(uintptr_t rep) { } } -uintptr_t Status::NewRep(absl::StatusCode code, absl::string_view msg, - std::unique_ptr payloads) { +uintptr_t Status::NewRep( + absl::StatusCode code, absl::string_view msg, + std::unique_ptr payloads) { status_internal::StatusRep* rep = new status_internal::StatusRep( - code, std::string(msg.data(), msg.size()), std::move(payloads)); + code, std::string(msg.data(), msg.size()), + std::move(payloads)); return PointerToRep(rep); } @@ -236,8 +238,9 @@ absl::StatusCode Status::code() const { void Status::PrepareToModify() { ABSL_RAW_CHECK(!ok(), "PrepareToModify shouldn't be called on OK status."); if (IsInlined(rep_)) { - rep_ = NewRep(static_cast(raw_code()), - absl::string_view(), nullptr); + rep_ = + NewRep(static_cast(raw_code()), absl::string_view(), + nullptr); return; } @@ -248,7 +251,8 @@ void Status::PrepareToModify() { if (rep->payloads) { payloads = absl::make_unique(*rep->payloads); } - rep_ = NewRep(rep->code, message(), std::move(payloads)); + rep_ = NewRep(rep->code, message(), + std::move(payloads)); UnrefNonInlined(rep_i); } } diff --git a/absl/status/status.h b/absl/status/status.h index 08d3e806..118f64fb 100644 --- a/absl/status/status.h +++ b/absl/status/status.h @@ -371,10 +371,10 @@ class ABSL_MUST_USE_RESULT Status final { Status(); // Creates a status in the canonical error space with the specified - // `absl::StatusCode` and error message. If `code == absl::StatusCode::kOk`, + // `absl::StatusCode` and error message. If `code == absl::StatusCode::kOk`, // NOLINT // `msg` is ignored and an object identical to an OK status is constructed. // - // The `msg` string must be in UTF-8. The implementation may complain (e.g., + // The `msg` string must be in UTF-8. The implementation may complain (e.g., // NOLINT // by printing a warning) if it is not. Status(absl::StatusCode code, absl::string_view msg); @@ -551,8 +551,9 @@ class ABSL_MUST_USE_RESULT Status final { status_internal::Payloads* GetPayloads(); // Takes ownership of payload. - static uintptr_t NewRep(absl::StatusCode code, absl::string_view msg, - std::unique_ptr payload); + static uintptr_t NewRep( + absl::StatusCode code, absl::string_view msg, + std::unique_ptr payload); static bool EqualsSlow(const absl::Status& a, const absl::Status& b); // MSVC 14.0 limitation requires the const. diff --git a/absl/strings/cord.cc b/absl/strings/cord.cc index df8c26d4..39191ef5 100644 --- a/absl/strings/cord.cc +++ b/absl/strings/cord.cc @@ -37,6 +37,7 @@ #include "absl/strings/escaping.h" #include "absl/strings/internal/cord_internal.h" #include "absl/strings/internal/cord_rep_flat.h" +#include "absl/strings/internal/cord_rep_ring.h" #include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -50,8 +51,8 @@ using ::absl::cord_internal::CordRep; using ::absl::cord_internal::CordRepConcat; using ::absl::cord_internal::CordRepExternal; using ::absl::cord_internal::CordRepFlat; +using ::absl::cord_internal::CordRepRing; using ::absl::cord_internal::CordRepSubstring; - using ::absl::cord_internal::kMinFlatLength; using ::absl::cord_internal::kMaxFlatLength; @@ -94,6 +95,11 @@ static constexpr uint64_t min_length[] = { static const int kMinLengthSize = ABSL_ARRAYSIZE(min_length); +static inline bool cord_ring_enabled() { + return cord_internal::cord_ring_buffer_enabled.load( + std::memory_order_relaxed); +} + static inline bool IsRootBalanced(CordRep* node) { if (node->tag != CONCAT) { return true; @@ -109,7 +115,8 @@ static inline bool IsRootBalanced(CordRep* node) { } static CordRep* Rebalance(CordRep* node); -static void DumpNode(CordRep* rep, bool include_data, std::ostream* os); +static void DumpNode(CordRep* rep, bool include_data, std::ostream* os, + int indent = 0); static bool VerifyNode(CordRep* root, CordRep* start_node, bool full_validation); @@ -198,12 +205,38 @@ static CordRep* MakeBalancedTree(CordRep** reps, size_t n) { return reps[0]; } +static CordRepFlat* CreateFlat(const char* data, size_t length, + size_t alloc_hint) { + CordRepFlat* flat = CordRepFlat::New(length + alloc_hint); + flat->length = length; + memcpy(flat->Data(), data, length); + return flat; +} + +// Creates a new flat or ringbuffer out of the specified array. +// The returned node has a refcount of 1. +static CordRep* RingNewTree(const char* data, size_t length, + size_t alloc_hint) { + if (length <= kMaxFlatLength) { + return CreateFlat(data, length, alloc_hint); + } + CordRepFlat* flat = CreateFlat(data, kMaxFlatLength, 0); + data += kMaxFlatLength; + length -= kMaxFlatLength; + size_t extra = (length - 1) / kMaxFlatLength + 1; + auto* root = CordRepRing::Create(flat, extra); + return CordRepRing::Append(root, {data, length}, alloc_hint); +} + // Create a new tree out of the specified array. // The returned node has a refcount of 1. static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) { if (length == 0) return nullptr; + if (cord_ring_enabled()) { + return RingNewTree(data, length, alloc_hint); + } absl::FixedArray reps((length - 1) / kMaxFlatLength + 1); size_t n = 0; do { @@ -295,10 +328,18 @@ inline void Cord::InlineRep::remove_prefix(size_t n) { reduce_size(n); } +// Returns `rep` converted into a CordRepRing. +// Directly returns `rep` if `rep` is already a CordRepRing. +static CordRepRing* ForceRing(CordRep* rep, size_t extra) { + return (rep->tag == RING) ? rep->ring() : CordRepRing::Create(rep, extra); +} + void Cord::InlineRep::AppendTree(CordRep* tree) { if (tree == nullptr) return; if (data_.is_empty()) { set_tree(tree); + } else if (cord_ring_enabled()) { + set_tree(CordRepRing::Append(ForceRing(force_tree(0), 1), tree)); } else { set_tree(Concat(force_tree(0), tree)); } @@ -308,6 +349,8 @@ void Cord::InlineRep::PrependTree(CordRep* tree) { assert(tree != nullptr); if (data_.is_empty()) { set_tree(tree); + } else if (cord_ring_enabled()) { + set_tree(CordRepRing::Prepend(ForceRing(force_tree(0), 1), tree)); } else { set_tree(Concat(tree, force_tree(0))); } @@ -319,6 +362,15 @@ void Cord::InlineRep::PrependTree(CordRep* tree) { // written to region and the actual size increase will be written to size. static inline bool PrepareAppendRegion(CordRep* root, char** region, size_t* size, size_t max_length) { + if (root->tag == RING && root->refcount.IsOne()) { + Span span = root->ring()->GetAppendBuffer(max_length); + if (!span.empty()) { + *region = span.data(); + *size = span.size(); + return true; + } + } + // Search down the right-hand path for a non-full FLAT node. CordRep* dst = root; while (dst->tag == CONCAT && dst->refcount.IsOne()) { @@ -383,6 +435,11 @@ void Cord::InlineRep::GetAppendRegion(char** region, size_t* size, new_node->length = std::min(new_node->Capacity(), max_length); *region = new_node->Data(); *size = new_node->length; + + if (cord_ring_enabled()) { + replace_tree(CordRepRing::Append(ForceRing(root, 1), new_node)); + return; + } replace_tree(Concat(root, new_node)); } @@ -411,6 +468,11 @@ void Cord::InlineRep::GetAppendRegion(char** region, size_t* size) { new_node->length = new_node->Capacity(); *region = new_node->Data(); *size = new_node->length; + + if (cord_ring_enabled()) { + replace_tree(CordRepRing::Append(ForceRing(root, 1), new_node)); + return; + } replace_tree(Concat(root, new_node)); } @@ -593,6 +655,13 @@ void Cord::InlineRep::AppendArray(const char* src_data, size_t src_size) { return; } + if (cord_ring_enabled()) { + absl::string_view data(src_data, src_size); + root = ForceRing(root, (data.size() - 1) / kMaxFlatLength + 1); + replace_tree(CordRepRing::Append(root->ring(), data)); + return; + } + // Use new block(s) for any remaining bytes that were not handled above. // Alloc extra memory only if the right child of the root of the new tree is // going to be a FLAT node, which will permit further inplace appends. @@ -805,6 +874,8 @@ void Cord::RemovePrefix(size_t n) { CordRep* tree = contents_.tree(); if (tree == nullptr) { contents_.remove_prefix(n); + } else if (tree->tag == RING) { + contents_.replace_tree(CordRepRing::RemovePrefix(tree->ring(), n)); } else { CordRep* newrep = RemovePrefixFrom(tree, n); CordRep::Unref(tree); @@ -819,6 +890,8 @@ void Cord::RemoveSuffix(size_t n) { CordRep* tree = contents_.tree(); if (tree == nullptr) { contents_.reduce_size(n); + } else if (tree->tag == RING) { + contents_.replace_tree(CordRepRing::RemoveSuffix(tree->ring(), n)); } else { CordRep* newrep = RemoveSuffixFrom(tree, n); CordRep::Unref(tree); @@ -902,6 +975,9 @@ Cord Cord::Subcord(size_t pos, size_t new_size) const { } cord_internal::SmallMemmove(dest, it->data(), remaining_size); sub_cord.contents_.set_inline_size(new_size); + } else if (tree->tag == RING) { + tree = CordRepRing::SubRing(CordRep::Ref(tree)->ring(), pos, new_size); + sub_cord.contents_.set_tree(tree); } else { sub_cord.contents_.set_tree(NewSubRange(tree, pos, new_size)); } @@ -1103,6 +1179,10 @@ inline absl::string_view Cord::InlineRep::FindFlatStartPiece() const { return absl::string_view(node->external()->base, node->length); } + if (node->tag == RING) { + return node->ring()->entry_data(node->ring()->head()); + } + // Walk down the left branches until we hit a non-CONCAT node. while (node->tag == CONCAT) { node = node->concat()->left; @@ -1360,6 +1440,25 @@ Cord Cord::ChunkIterator::AdvanceAndReadBytes(size_t n) { } return subcord; } + + if (ring_reader_) { + size_t chunk_size = current_chunk_.size(); + if (n <= chunk_size && n <= kMaxBytesToCopy) { + subcord = Cord(current_chunk_.substr(0, n)); + } else { + auto* ring = CordRep::Ref(ring_reader_.ring())->ring(); + size_t offset = ring_reader_.length() - bytes_remaining_; + subcord.contents_.set_tree(CordRepRing::SubRing(ring, offset, n)); + } + if (n < chunk_size) { + bytes_remaining_ -= n; + current_chunk_.remove_prefix(n); + } else { + AdvanceBytesRing(n); + } + return subcord; + } + auto& stack_of_right_children = stack_of_right_children_; if (n < current_chunk_.size()) { // Range to read is a proper subrange of the current chunk. @@ -1533,6 +1632,8 @@ char Cord::operator[](size_t i) const { if (rep->tag >= FLAT) { // Get the "i"th character directly from the flat array. return rep->flat()->Data()[offset]; + } else if (rep->tag == RING) { + return rep->ring()->GetCharacter(offset); } else if (rep->tag == EXTERNAL) { // Get the "i"th character from the external array. return rep->external()->base[offset]; @@ -1609,6 +1710,15 @@ absl::string_view Cord::FlattenSlowPath() { /* static */ void Cord::ForEachChunkAux( absl::cord_internal::CordRep* rep, absl::FunctionRef callback) { + if (rep->tag == RING) { + ChunkIterator it(rep), end; + while (it != end) { + callback(*it); + ++it; + } + return; + } + assert(rep != nullptr); int stack_pos = 0; constexpr int stack_max = 128; @@ -1650,9 +1760,9 @@ absl::string_view Cord::FlattenSlowPath() { } } -static void DumpNode(CordRep* rep, bool include_data, std::ostream* os) { +static void DumpNode(CordRep* rep, bool include_data, std::ostream* os, + int indent) { const int kIndentStep = 1; - int indent = 0; absl::InlinedVector stack; absl::InlinedVector indents; for (;;) { @@ -1673,18 +1783,28 @@ static void DumpNode(CordRep* rep, bool include_data, std::ostream* os) { *os << "SUBSTRING @ " << rep->substring()->start << "\n"; indent += kIndentStep; rep = rep->substring()->child; - } else { // Leaf + } else { // Leaf or ring if (rep->tag == EXTERNAL) { *os << "EXTERNAL ["; if (include_data) *os << absl::CEscape(std::string(rep->external()->base, rep->length)); *os << "]\n"; - } else { + } else if (rep->tag >= FLAT) { *os << "FLAT cap=" << rep->flat()->Capacity() << " ["; if (include_data) *os << absl::CEscape(std::string(rep->flat()->Data(), rep->length)); *os << "]\n"; + } else { + assert(rep->tag == RING); + auto* ring = rep->ring(); + *os << "RING, entries = " << ring->entries() << "\n"; + CordRepRing::index_type head = ring->head(); + do { + DumpNode(ring->entry_child(head), include_data, os, + indent + kIndentStep); + head = ring->advance(head);; + } while (head != ring->tail()); } if (stack.empty()) break; rep = stack.back(); @@ -1778,6 +1898,15 @@ static bool VerifyNode(CordRep* root, CordRep* start_node, } next_node = right; } + } else if (cur_node->tag == RING) { + total_mem_usage += CordRepRing::AllocSize(cur_node->ring()->capacity()); + const CordRepRing* ring = cur_node->ring(); + CordRepRing::index_type pos = ring->head(), tail = ring->tail(); + do { + CordRep* node = ring->entry_child(pos); + assert(node->tag >= FLAT || node->tag == EXTERNAL); + RepMemoryUsageLeaf(node, &total_mem_usage); + } while ((pos = ring->advance(pos)) != tail); } else { // Since cur_node is not a leaf or a concat node it must be a substring. assert(cur_node->tag == SUBSTRING); diff --git a/absl/strings/cord.h b/absl/strings/cord.h index abef98fe..17341bda 100644 --- a/absl/strings/cord.h +++ b/absl/strings/cord.h @@ -78,6 +78,8 @@ #include "absl/functional/function_ref.h" #include "absl/meta/type_traits.h" #include "absl/strings/internal/cord_internal.h" +#include "absl/strings/internal/cord_rep_ring.h" +#include "absl/strings/internal/cord_rep_ring_reader.h" #include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/internal/string_constant.h" #include "absl/strings/string_view.h" @@ -361,6 +363,10 @@ class Cord { friend class CharIterator; private: + using CordRep = absl::cord_internal::CordRep; + using CordRepRing = absl::cord_internal::CordRepRing; + using CordRepRingReader = absl::cord_internal::CordRepRingReader; + // Stack of right children of concat nodes that we have to visit. // Keep this at the end of the structure to avoid cache-thrashing. // TODO(jgm): Benchmark to see if there's a more optimal value than 47 for @@ -385,6 +391,10 @@ class Cord { // Stack specific operator++ ChunkIterator& AdvanceStack(); + // Ring buffer specific operator++ + ChunkIterator& AdvanceRing(); + void AdvanceBytesRing(size_t n); + // Iterates `n` bytes, where `n` is expected to be greater than or equal to // `current_chunk_.size()`. void AdvanceBytesSlowPath(size_t n); @@ -398,6 +408,10 @@ class Cord { absl::cord_internal::CordRep* current_leaf_ = nullptr; // The number of bytes left in the `Cord` over which we are iterating. size_t bytes_remaining_ = 0; + + // Cord reader for ring buffers. Empty if not traversing a ring buffer. + CordRepRingReader ring_reader_; + // See 'Stack' alias definition. Stack stack_of_right_children_; }; @@ -1107,6 +1121,11 @@ inline bool Cord::StartsWith(absl::string_view rhs) const { } inline void Cord::ChunkIterator::InitTree(cord_internal::CordRep* tree) { + if (tree->tag == cord_internal::RING) { + current_chunk_ = ring_reader_.Reset(tree->ring()); + return; + } + stack_of_right_children_.push_back(tree); operator++(); } @@ -1126,13 +1145,33 @@ inline Cord::ChunkIterator::ChunkIterator(const Cord* cord) } } +inline Cord::ChunkIterator& Cord::ChunkIterator::AdvanceRing() { + current_chunk_ = ring_reader_.Next(); + return *this; +} + +inline void Cord::ChunkIterator::AdvanceBytesRing(size_t n) { + assert(n >= current_chunk_.size()); + bytes_remaining_ -= n; + if (bytes_remaining_) { + if (n == current_chunk_.size()) { + current_chunk_ = ring_reader_.Next(); + } else { + size_t offset = ring_reader_.length() - bytes_remaining_; + current_chunk_ = ring_reader_.Seek(offset); + } + } else { + current_chunk_ = {}; + } +} + inline Cord::ChunkIterator& Cord::ChunkIterator::operator++() { ABSL_HARDENING_ASSERT(bytes_remaining_ > 0 && "Attempted to iterate past `end()`"); assert(bytes_remaining_ >= current_chunk_.size()); bytes_remaining_ -= current_chunk_.size(); if (bytes_remaining_ > 0) { - return AdvanceStack(); + return ring_reader_ ? AdvanceRing() : AdvanceStack(); } else { current_chunk_ = {}; } @@ -1174,7 +1213,7 @@ inline void Cord::ChunkIterator::AdvanceBytes(size_t n) { if (ABSL_PREDICT_TRUE(n < current_chunk_.size())) { RemoveChunkPrefix(n); } else if (n != 0) { - AdvanceBytesSlowPath(n); + ring_reader_ ? AdvanceBytesRing(n) : AdvanceBytesSlowPath(n); } } diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc index 7942bfc0..bf7a6820 100644 --- a/absl/strings/cord_test.cc +++ b/absl/strings/cord_test.cc @@ -367,7 +367,7 @@ TEST(Cord, Subcord) { for (size_t end_pos : positions) { if (end_pos < pos || end_pos > a.size()) continue; absl::Cord sa = a.Subcord(pos, end_pos - pos); - EXPECT_EQ(absl::string_view(s).substr(pos, end_pos - pos), + ASSERT_EQ(absl::string_view(s).substr(pos, end_pos - pos), std::string(sa)) << a; } @@ -379,7 +379,7 @@ TEST(Cord, Subcord) { for (size_t pos = 0; pos <= sh.size(); ++pos) { for (size_t n = 0; n <= sh.size() - pos; ++n) { absl::Cord sc = c.Subcord(pos, n); - EXPECT_EQ(sh.substr(pos, n), std::string(sc)) << c; + ASSERT_EQ(sh.substr(pos, n), std::string(sc)) << c; } } @@ -389,7 +389,7 @@ TEST(Cord, Subcord) { while (sa.size() > 1) { sa = sa.Subcord(1, sa.size() - 2); ss = ss.substr(1, ss.size() - 2); - EXPECT_EQ(ss, std::string(sa)) << a; + ASSERT_EQ(ss, std::string(sa)) << a; if (HasFailure()) break; // halt cascade } diff --git a/absl/strings/internal/cord_rep_flat.h b/absl/strings/internal/cord_rep_flat.h index 55418153..a98aa9df 100644 --- a/absl/strings/internal/cord_rep_flat.h +++ b/absl/strings/internal/cord_rep_flat.h @@ -43,8 +43,9 @@ static constexpr size_t kMaxFlatSize = 4096; static constexpr size_t kMaxFlatLength = kMaxFlatSize - kFlatOverhead; static constexpr size_t kMinFlatLength = kMinFlatSize - kFlatOverhead; -constexpr size_t AllocatedSizeToTagUnchecked(size_t size) { - return (size <= 1024) ? size / 8 : 128 + size / 32 - 1024 / 32; +constexpr uint8_t AllocatedSizeToTagUnchecked(size_t size) { + return static_cast((size <= 1024) ? size / 8 + : 128 + size / 32 - 1024 / 32); } static_assert(kMinFlatSize / 8 >= FLAT, ""); @@ -65,7 +66,7 @@ inline size_t RoundUpForTag(size_t size) { // undefined if the size exceeds the maximum size that can be encoded in // a tag, i.e., if size is larger than TagToAllocatedSize(). inline uint8_t AllocatedSizeToTag(size_t size) { - const size_t tag = AllocatedSizeToTagUnchecked(size); + const uint8_t tag = AllocatedSizeToTagUnchecked(size); assert(tag <= MAX_FLAT_TAG); return tag; } diff --git a/absl/strings/internal/cord_rep_ring.cc b/absl/strings/internal/cord_rep_ring.cc index 358b0d92..4d31d1d9 100644 --- a/absl/strings/internal/cord_rep_ring.cc +++ b/absl/strings/internal/cord_rep_ring.cc @@ -36,8 +36,10 @@ namespace cord_internal { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wshadow" +#if __has_warning("-Wshadow-field") #pragma clang diagnostic ignored "-Wshadow-field" #endif +#endif namespace { diff --git a/absl/strings/internal/cord_rep_ring.h b/absl/strings/internal/cord_rep_ring.h index 55cba8b4..c74d3353 100644 --- a/absl/strings/internal/cord_rep_ring.h +++ b/absl/strings/internal/cord_rep_ring.h @@ -34,8 +34,10 @@ namespace cord_internal { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wshadow" +#if __has_warning("-Wshadow-field") #pragma clang diagnostic ignored "-Wshadow-field" #endif +#endif // All operations modifying a ring buffer are implemented as static methods // requiring a CordRepRing instance with a reference adopted by the method. @@ -81,7 +83,7 @@ class CordRepRing : public CordRep { // `end_pos` which is the `end_pos` of the previous node (or `begin_pos`) plus // this node's length. The purpose is to allow for a binary search on this // position, while allowing O(1) prepend and append operations. - using pos_type = uint64_t; + using pos_type = size_t; // `index_type` is the type for the `head`, `tail` and `capacity` indexes. // Ring buffers are limited to having no more than four billion entries. diff --git a/absl/time/internal/cctz/testdata/version b/absl/time/internal/cctz/testdata/version index a481df8c..1d590958 100644 --- a/absl/time/internal/cctz/testdata/version +++ b/absl/time/internal/cctz/testdata/version @@ -1 +1 @@ -2020f +2021a diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba index 36b05220..0aba9ffd 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba and b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Juba differ -- cgit v1.2.3 From b315753c0b8b4aa4e3e1479375eddb518393bab6 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 17 Feb 2021 09:48:49 -0800 Subject: Export of internal Abseil changes -- 2247e59ee5696e61c7cb24dce479db572980032d by Derek Mauro : Ensure ThreadIdentity::WaiterState data has the correct alignment PiperOrigin-RevId: 357969866 -- 79bb81a2e6723b186536ad4b4f25cd7ee83f3e72 by Laramie Leavitt : Rework absl::MockingBitGen internal mock registry. Use a virtual base class with template-specialized derived classes to implement match method rather than taking the address of a function specialization and using casts everywhere. This combines several of the previously type-erased pointers into a single object, eliminates the separate cleanup container previously used, and eliminates some gratuitous static_cast<>s. PiperOrigin-RevId: 357827438 -- a2eb53d002c9b376360a70b2b0f6a18a1de1e16f by Todd Lipcon : Reduce runtime of sequence_lock_test PiperOrigin-RevId: 357785571 -- dd1175ff13b560f01c4aaa64bc6759a5300e391c by Abseil Team : Don't assume that compiling for Windows means that MSVC or clang-cl is being used. PiperOrigin-RevId: 357760052 -- 251a9cbede52e729b3a25911b6e225b779c285a8 by Andy Getzendanner : Internal change. PiperOrigin-RevId: 357702979 GitOrigin-RevId: 2247e59ee5696e61c7cb24dce479db572980032d Change-Id: Icd366d3775d88d623695209b5f328dbd69f01d27 --- absl/BUILD.bazel | 25 +++++---- absl/base/BUILD.bazel | 8 ++- absl/base/config.h | 2 + absl/base/internal/thread_identity.h | 2 +- absl/copts/configure_copts.bzl | 8 +-- absl/debugging/BUILD.bazel | 12 +++-- absl/flags/BUILD.bazel | 2 +- absl/flags/internal/sequence_lock_test.cc | 16 +++++- absl/random/internal/BUILD.bazel | 9 ++-- absl/random/mocking_bit_gen.h | 87 +++++++++++++++---------------- absl/synchronization/BUILD.bazel | 3 +- 11 files changed, 105 insertions(+), 69 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/BUILD.bazel b/absl/BUILD.bazel index 6da20c49..c9d4a2da 100644 --- a/absl/BUILD.bazel +++ b/absl/BUILD.bazel @@ -25,6 +25,22 @@ config_setting( visibility = [":__subpackages__"], ) +config_setting( + name = "msvc_compiler", + flag_values = { + "@bazel_tools//tools/cpp:compiler": "msvc-cl", + }, + visibility = [":__subpackages__"], +) + +config_setting( + name = "clang-cl_compiler", + flag_values = { + "@bazel_tools//tools/cpp:compiler": "clang-cl", + }, + visibility = [":__subpackages__"], +) + config_setting( name = "osx", constraint_values = [ @@ -39,15 +55,6 @@ config_setting( ], ) -config_setting( - name = "windows", - constraint_values = [ - "@bazel_tools//platforms:x86_64", - "@bazel_tools//platforms:windows", - ], - visibility = [":__subpackages__"], -) - config_setting( name = "ppc", values = { diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 7d2ff308..65ff0dde 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -160,7 +160,8 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = select({ - "//absl:windows": [], + "//absl:msvc_compiler": [], + "//absl:clang-cl_compiler": [], "//absl:wasm": [], "//conditions:default": ["-pthread"], }) + ABSL_DEFAULT_LINKOPTS, @@ -220,7 +221,10 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = select({ - "//absl:windows": [ + "//absl:msvc_compiler": [ + "-DEFAULTLIB:advapi32.lib", + ], + "//absl:clang-cl_compiler": [ "-DEFAULTLIB:advapi32.lib", ], "//absl:wasm": [], diff --git a/absl/base/config.h b/absl/base/config.h index 3d6aa178..444330d3 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -216,6 +216,8 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #if ABSL_INTERNAL_HAS_KEYWORD(__builtin_LINE) && \ ABSL_INTERNAL_HAS_KEYWORD(__builtin_FILE) #define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1 +#elif defined(__GNUC__) && __GNUC__ >= 5 +#define ABSL_HAVE_SOURCE_LOCATION_CURRENT 1 #endif #endif diff --git a/absl/base/internal/thread_identity.h b/absl/base/internal/thread_identity.h index d2a65fd8..9ee651a3 100644 --- a/absl/base/internal/thread_identity.h +++ b/absl/base/internal/thread_identity.h @@ -143,7 +143,7 @@ struct ThreadIdentity { // Private: Reserved for absl::synchronization_internal::Waiter. struct WaiterState { - char data[128]; + alignas(void*) char data[128]; } waiter_state; // Used by PerThreadSem::{Get,Set}ThreadBlockedCounter(). diff --git a/absl/copts/configure_copts.bzl b/absl/copts/configure_copts.bzl index 4d342544..669a9060 100644 --- a/absl/copts/configure_copts.bzl +++ b/absl/copts/configure_copts.bzl @@ -22,19 +22,21 @@ load( ) ABSL_DEFAULT_COPTS = select({ - "//absl:windows": ABSL_MSVC_FLAGS, + "//absl:msvc_compiler": ABSL_MSVC_FLAGS, + "//absl:clang-cl_compiler": ABSL_CLANG_CL_FLAGS, "//absl:clang_compiler": ABSL_LLVM_FLAGS, "//conditions:default": ABSL_GCC_FLAGS, }) ABSL_TEST_COPTS = ABSL_DEFAULT_COPTS + select({ - "//absl:windows": ABSL_MSVC_TEST_FLAGS, + "//absl:msvc_compiler": ABSL_MSVC_TEST_FLAGS, + "//absl:clang-cl_compiler": ABSL_CLANG_CL_TEST_FLAGS, "//absl:clang_compiler": ABSL_LLVM_TEST_FLAGS, "//conditions:default": ABSL_GCC_TEST_FLAGS, }) ABSL_DEFAULT_LINKOPTS = select({ - "//absl:windows": ABSL_MSVC_LINKOPTS, + "//absl:msvc_compiler": ABSL_MSVC_LINKOPTS, "//conditions:default": [], }) diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index cd6e4543..e7fd1152 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -66,7 +66,8 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS + select({ - "//absl:windows": ["-DEFAULTLIB:dbghelp.lib"], + "//absl:msvc_compiler": ["-DEFAULTLIB:dbghelp.lib"], + "//absl:clang-cl_compiler": ["-DEFAULTLIB:dbghelp.lib"], "//conditions:default": [], }), deps = [ @@ -86,11 +87,13 @@ cc_test( name = "symbolize_test", srcs = ["symbolize_test.cc"], copts = ABSL_TEST_COPTS + select({ - "//absl:windows": ["/Z7"], + "//absl:msvc_compiler": ["/Z7"], + "//absl:clang-cl_compiler": ["/Z7"], "//conditions:default": [], }), linkopts = ABSL_DEFAULT_LINKOPTS + select({ - "//absl:windows": ["/DEBUG"], + "//absl:msvc_compiler": ["/DEBUG"], + "//absl:clang-cl_compiler": ["/DEBUG"], "//conditions:default": [], }), deps = [ @@ -148,7 +151,8 @@ cc_test( srcs = ["failure_signal_handler_test.cc"], copts = ABSL_TEST_COPTS, linkopts = select({ - "//absl:windows": [], + "//absl:msvc_compiler": [], + "//absl:clang-cl_compiler": [], "//absl:wasm": [], "//conditions:default": ["-pthread"], }) + ABSL_DEFAULT_LINKOPTS, diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 1937609a..147249ed 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -488,7 +488,7 @@ cc_test( ], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, - shard_count = 32, + shard_count = 31, deps = [ ":flag_internal", "//absl/base", diff --git a/absl/flags/internal/sequence_lock_test.cc b/absl/flags/internal/sequence_lock_test.cc index ff8b476b..c3ec372e 100644 --- a/absl/flags/internal/sequence_lock_test.cc +++ b/absl/flags/internal/sequence_lock_test.cc @@ -121,11 +121,25 @@ const int kMaxThreads = absl::base_internal::NumCPUs(); const int kMaxThreads = std::min(absl::base_internal::NumCPUs(), 4); #endif +// Return all of the interesting buffer sizes worth testing: +// powers of two and adjacent values. +std::vector InterestingBufferSizes() { + std::vector ret; + for (int v : MultiplicativeRange(1, 128, 2)) { + ret.push_back(v); + if (v > 1) { + ret.push_back(v - 1); + } + ret.push_back(v + 1); + } + return ret; +} + INSTANTIATE_TEST_SUITE_P( TestManyByteSizes, ConcurrentSequenceLockTest, testing::Combine( // Buffer size (bytes). - testing::Range(1, 128), + testing::ValuesIn(InterestingBufferSizes()), // Number of reader threads. testing::ValuesIn(MultiplicativeRange(1, kMaxThreads, 2)))); diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index 4e778aee..612b1505 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -75,7 +75,8 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS + select({ - "//absl:windows": ["-DEFAULTLIB:bcrypt.lib"], + "//absl:msvc_compiler": ["-DEFAULTLIB:bcrypt.lib"], + "//absl:clang-cl_compiler": ["-DEFAULTLIB:bcrypt.lib"], "//conditions:default": [], }), deps = [ @@ -98,7 +99,8 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = select({ - "//absl:windows": [], + "//absl:msvc_compiler": [], + "//absl:clang-cl_compiler": [], "//absl:wasm": [], "//conditions:default": ["-pthread"], }) + ABSL_DEFAULT_LINKOPTS, @@ -325,7 +327,8 @@ cc_library( "randen_hwaes.h", ], copts = ABSL_DEFAULT_COPTS + ABSL_RANDOM_RANDEN_COPTS + select({ - "//absl:windows": [], + "//absl:msvc_compiler": [], + "//absl:clang-cl_compiler": [], "//conditions:default": ["-Wno-pass-failed"], }), linkopts = ABSL_DEFAULT_LINKOPTS, diff --git a/absl/random/mocking_bit_gen.h b/absl/random/mocking_bit_gen.h index 6d2f2c83..6815ca44 100644 --- a/absl/random/mocking_bit_gen.h +++ b/absl/random/mocking_bit_gen.h @@ -104,10 +104,7 @@ class BitGenRef; class MockingBitGen { public: MockingBitGen() = default; - - ~MockingBitGen() { - for (const auto& del : deleters_) del(); - } + ~MockingBitGen() = default; // URBG interface using result_type = absl::BitGen::result_type; @@ -117,14 +114,6 @@ class MockingBitGen { result_type operator()() { return gen_(); } private: - using match_impl_fn = void (*)(void* mock_fn, void* t_erased_arg_tuple, - void* t_erased_result); - - struct MockData { - void* mock_fn = nullptr; - match_impl_fn match_impl = nullptr; - }; - // GetMockFnType returns the testing::MockFunction for a result and tuple. // This method only exists for type deduction and is otherwise unimplemented. template @@ -136,17 +125,46 @@ class MockingBitGen { // NOTE: MockFnCaller is essentially equivalent to the lambda: // [fn](auto... args) { return fn->Call(std::move(args)...)} // however that fails to build on some supported platforms. - template + template struct MockFnCaller; + // specialization for std::tuple. - template - struct MockFnCaller> { + template + struct MockFnCaller> { MockFnType* fn; inline ResultT operator()(Args... args) { return fn->Call(std::move(args)...); } }; + // FunctionHolder owns a particular ::testing::MockFunction associated with + // a mocked type signature, and implement the type-erased Apply call, which + // applies type-erased arguments to the mock. + class FunctionHolder { + public: + virtual ~FunctionHolder() = default; + + // Call is a dispatch function which converts the + // generic type-erased parameters into a specific mock invocation call. + virtual void Apply(/*ArgTupleT*/ void* args_tuple, + /*ResultT*/ void* result) = 0; + }; + + template + class FunctionHolderImpl final : public FunctionHolder { + public: + void Apply(void* args_tuple, void* result) override { + // Requires tuple_args to point to a ArgTupleT, which is a + // std::tuple used to invoke the mock function. Requires result + // to point to a ResultT, which is the result of the call. + *static_cast(result) = + absl::apply(MockFnCaller{&mock_fn_}, + *static_cast(args_tuple)); + } + + MockFnType mock_fn_; + }; + // MockingBitGen::RegisterMock // // RegisterMock(FastTypeIdType) is the main extension @@ -161,33 +179,14 @@ class MockingBitGen { auto RegisterMock(base_internal::FastTypeIdType type) -> decltype(GetMockFnType(std::declval(), std::declval()))& { - using MockFnType = decltype( - GetMockFnType(std::declval(), std::declval())); + using MockFnType = decltype(GetMockFnType(std::declval(), + std::declval())); + using ImplT = FunctionHolderImpl; auto& mock = mocks_[type]; - if (!mock.mock_fn) { - auto* mock_fn = new MockFnType; - mock.mock_fn = mock_fn; - mock.match_impl = &MatchImpl; - deleters_.emplace_back([mock_fn] { delete mock_fn; }); + if (!mock) { + mock = absl::make_unique(); } - return *static_cast(mock.mock_fn); - } - - // MockingBitGen::MatchImpl<> is a dispatch function which converts the - // generic type-erased parameters into a specific mock invocation call. - // Requires tuple_args to point to a ArgTupleT, which is a std::tuple - // used to invoke the mock function. - // Requires result to point to a ResultT, which is the result of the call. - template - static void MatchImpl(/*MockFnType*/ void* mock_fn, - /*ArgTupleT*/ void* args_tuple, - /*ResultT*/ void* result) { - using MockFnType = decltype( - GetMockFnType(std::declval(), std::declval())); - *static_cast(result) = absl::apply( - MockFnCaller{ - static_cast(mock_fn)}, - *static_cast(args_tuple)); + return static_cast(mock.get())->mock_fn_; } // MockingBitGen::InvokeMock @@ -206,13 +205,13 @@ class MockingBitGen { // Trigger a mock, if there exists one that matches `param`. auto it = mocks_.find(type); if (it == mocks_.end()) return false; - auto* mock_data = static_cast(&it->second); - mock_data->match_impl(mock_data->mock_fn, args_tuple, result); + it->second->Apply(args_tuple, result); return true; } - absl::flat_hash_map mocks_; - std::vector> deleters_; + absl::flat_hash_map> + mocks_; absl::BitGen gen_; template diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index cd4009a1..5ce16958 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -88,7 +88,8 @@ cc_library( ], copts = ABSL_DEFAULT_COPTS, linkopts = select({ - "//absl:windows": [], + "//absl:msvc_compiler": [], + "//absl:clang-cl_compiler": [], "//absl:wasm": [], "//conditions:default": ["-pthread"], }) + ABSL_DEFAULT_LINKOPTS, -- cgit v1.2.3 From 0b5af594fc200b77b130dd65d2412bdd8e1e2c76 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 19 Feb 2021 10:26:08 -0800 Subject: Export of internal Abseil changes -- 1a5831c2b4b85e0151b7952e47f4b80827937620 by Laramie Leavitt : Implement FuzzingBitGen, an adapter which allows existing randomized tests which use absl::BitGenRef to easily integrate with fuzz testing. I found myself implementing a similar option in our tensorstore project to fuzz test a storage layer and figured that it would be more useful as a common tool with defaults that take the non-random path. This is similar to the FuzzedDataProvider mechanism which generates random values from a fuzz string, and is used to generate fuzz test inputs, and internally it uses FuzzedDataProvider. The basic technique used here is to construct mocking lambdas for all of the absl mock distribution configurations, and forwarding the parameters to fuzzing-specific implementations that call into FuzzedDataProvider. The default paths for the distributions are either the bounds or a median value. PiperOrigin-RevId: 358432715 -- e7968538c5ef5cd0b9822dbeac0f659b5e7d49b3 by Derek Mauro : Give extern C symbols a unique name when the inline namespace is given. This partially addresses #851 PiperOrigin-RevId: 358403842 GitOrigin-RevId: 1a5831c2b4b85e0151b7952e47f4b80827937620 Change-Id: Id5ca0251498e390a8efa7210a17cc2cabb2c7dd8 --- absl/base/config.h | 6 ++++ absl/base/dynamic_annotations.h | 34 +++++++++++++++------- absl/base/internal/spinlock_akaros.inc | 4 +-- absl/base/internal/spinlock_linux.inc | 6 ++-- absl/base/internal/spinlock_posix.inc | 4 +-- absl/base/internal/spinlock_wait.h | 10 ++++--- absl/base/internal/spinlock_win32.inc | 10 +++---- absl/container/internal/hashtablez_sampler.cc | 4 ++- absl/container/internal/hashtablez_sampler.h | 2 +- .../hashtablez_sampler_force_weak_definition.cc | 3 +- absl/flags/usage_config.cc | 5 ++-- absl/flags/usage_config.h | 3 +- absl/random/internal/mock_helpers.h | 17 +++++++---- absl/synchronization/internal/per_thread_sem.cc | 4 +-- absl/synchronization/internal/per_thread_sem.h | 8 ++--- absl/synchronization/mutex.cc | 6 ++-- absl/synchronization/mutex.h | 2 +- absl/time/clock.cc | 3 +- absl/time/clock.h | 4 +-- 19 files changed, 86 insertions(+), 49 deletions(-) (limited to 'absl/base/config.h') diff --git a/absl/base/config.h b/absl/base/config.h index 444330d3..95449969 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -121,10 +121,16 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #if ABSL_OPTION_USE_INLINE_NAMESPACE == 0 #define ABSL_NAMESPACE_BEGIN #define ABSL_NAMESPACE_END +#define ABSL_INTERNAL_C_SYMBOL(x) x #elif ABSL_OPTION_USE_INLINE_NAMESPACE == 1 #define ABSL_NAMESPACE_BEGIN \ inline namespace ABSL_OPTION_INLINE_NAMESPACE_NAME { #define ABSL_NAMESPACE_END } +#define ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v) x##_##v +#define ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, v) \ + ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v) +#define ABSL_INTERNAL_C_SYMBOL(x) \ + ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, ABSL_OPTION_INLINE_NAMESPACE_NAME) #else #error options.h is misconfigured. #endif diff --git a/absl/base/dynamic_annotations.h b/absl/base/dynamic_annotations.h index 545f8cbc..880cbf6e 100644 --- a/absl/base/dynamic_annotations.h +++ b/absl/base/dynamic_annotations.h @@ -110,6 +110,9 @@ // Define race annotations. #if ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 1 +// Some of the symbols used in this section (e.g. AnnotateBenignRaceSized) are +// defined by the compiler-based santizer implementation, not by the Abseil +// library. Therefore they do not use ABSL_INTERNAL_C_SYMBOL. // ------------------------------------------------------------- // Annotations that suppress errors. It is usually better to express the @@ -286,17 +289,22 @@ ABSL_INTERNAL_END_EXTERN_C // Define IGNORE_READS_BEGIN/_END annotations. #if ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED == 1 +// Some of the symbols used in this section (e.g. AnnotateIgnoreReadsBegin) are +// defined by the compiler-based implementation, not by the Abseil +// library. Therefore they do not use ABSL_INTERNAL_C_SYMBOL. // Request the analysis tool to ignore all reads in the current thread until // ABSL_ANNOTATE_IGNORE_READS_END is called. Useful to ignore intentional racey // reads, while still checking other reads and all writes. // See also ABSL_ANNOTATE_UNPROTECTED_READ. -#define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsBegin)(__FILE__, __LINE__) +#define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsBegin) \ + (__FILE__, __LINE__) // Stop ignoring reads. -#define ABSL_ANNOTATE_IGNORE_READS_END() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsEnd)(__FILE__, __LINE__) +#define ABSL_ANNOTATE_IGNORE_READS_END() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsEnd) \ + (__FILE__, __LINE__) // Function prototypes of annotations provided by the compiler-based sanitizer // implementation. @@ -316,16 +324,22 @@ ABSL_INTERNAL_END_EXTERN_C // TODO(delesley) -- The exclusive lock here ignores writes as well, but // allows IGNORE_READS_AND_WRITES to work properly. -#define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsBegin)() +#define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ + ABSL_INTERNAL_GLOBAL_SCOPED( \ + ABSL_INTERNAL_C_SYMBOL(AbslInternalAnnotateIgnoreReadsBegin)) \ + () -#define ABSL_ANNOTATE_IGNORE_READS_END() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsEnd)() +#define ABSL_ANNOTATE_IGNORE_READS_END() \ + ABSL_INTERNAL_GLOBAL_SCOPED( \ + ABSL_INTERNAL_C_SYMBOL(AbslInternalAnnotateIgnoreReadsEnd)) \ + () -ABSL_INTERNAL_STATIC_INLINE void AbslInternalAnnotateIgnoreReadsBegin() +ABSL_INTERNAL_STATIC_INLINE void ABSL_INTERNAL_C_SYMBOL( + AbslInternalAnnotateIgnoreReadsBegin)() ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE {} -ABSL_INTERNAL_STATIC_INLINE void AbslInternalAnnotateIgnoreReadsEnd() +ABSL_INTERNAL_STATIC_INLINE void ABSL_INTERNAL_C_SYMBOL( + AbslInternalAnnotateIgnoreReadsEnd)() ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE {} #else diff --git a/absl/base/internal/spinlock_akaros.inc b/absl/base/internal/spinlock_akaros.inc index bc468940..7b0cada4 100644 --- a/absl/base/internal/spinlock_akaros.inc +++ b/absl/base/internal/spinlock_akaros.inc @@ -20,7 +20,7 @@ extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( std::atomic* /* lock_word */, uint32_t /* value */, int /* loop */, absl::base_internal::SchedulingMode /* mode */) { // In Akaros, one must take care not to call anything that could cause a @@ -29,7 +29,7 @@ ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( // arbitrary code. } -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)( std::atomic* /* lock_word */, bool /* all */) {} } // extern "C" diff --git a/absl/base/internal/spinlock_linux.inc b/absl/base/internal/spinlock_linux.inc index e31c6ed4..202f7cdf 100644 --- a/absl/base/internal/spinlock_linux.inc +++ b/absl/base/internal/spinlock_linux.inc @@ -56,7 +56,7 @@ static_assert(sizeof(std::atomic) == sizeof(int), extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( std::atomic *w, uint32_t value, int loop, absl::base_internal::SchedulingMode) { absl::base_internal::ErrnoSaver errno_saver; @@ -66,8 +66,8 @@ ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, &tm); } -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake(std::atomic *w, - bool all) { +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)( + std::atomic *w, bool all) { syscall(SYS_futex, w, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, all ? INT_MAX : 1, 0); } diff --git a/absl/base/internal/spinlock_posix.inc b/absl/base/internal/spinlock_posix.inc index fcd21b15..4f6f887d 100644 --- a/absl/base/internal/spinlock_posix.inc +++ b/absl/base/internal/spinlock_posix.inc @@ -25,7 +25,7 @@ extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( std::atomic* /* lock_word */, uint32_t /* value */, int loop, absl::base_internal::SchedulingMode /* mode */) { absl::base_internal::ErrnoSaver errno_saver; @@ -40,7 +40,7 @@ ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( } } -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)( std::atomic* /* lock_word */, bool /* all */) {} } // extern "C" diff --git a/absl/base/internal/spinlock_wait.h b/absl/base/internal/spinlock_wait.h index c34ce41c..579bd09f 100644 --- a/absl/base/internal/spinlock_wait.h +++ b/absl/base/internal/spinlock_wait.h @@ -71,21 +71,23 @@ ABSL_NAMESPACE_END // By changing our extension points to be extern "C", we dodge this // check. extern "C" { -void AbslInternalSpinLockWake(std::atomic *w, bool all); -void AbslInternalSpinLockDelay( +void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(std::atomic *w, + bool all); +void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( std::atomic *w, uint32_t value, int loop, absl::base_internal::SchedulingMode scheduling_mode); } inline void absl::base_internal::SpinLockWake(std::atomic *w, bool all) { - AbslInternalSpinLockWake(w, all); + ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(w, all); } inline void absl::base_internal::SpinLockDelay( std::atomic *w, uint32_t value, int loop, absl::base_internal::SchedulingMode scheduling_mode) { - AbslInternalSpinLockDelay(w, value, loop, scheduling_mode); + ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay) + (w, value, loop, scheduling_mode); } #endif // ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_ diff --git a/absl/base/internal/spinlock_win32.inc b/absl/base/internal/spinlock_win32.inc index 78654b5b..9d224813 100644 --- a/absl/base/internal/spinlock_win32.inc +++ b/absl/base/internal/spinlock_win32.inc @@ -20,9 +20,9 @@ extern "C" { -void AbslInternalSpinLockDelay(std::atomic* /* lock_word */, - uint32_t /* value */, int loop, - absl::base_internal::SchedulingMode /* mode */) { +void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( + std::atomic* /* lock_word */, uint32_t /* value */, int loop, + absl::base_internal::SchedulingMode /* mode */) { if (loop == 0) { } else if (loop == 1) { Sleep(0); @@ -31,7 +31,7 @@ void AbslInternalSpinLockDelay(std::atomic* /* lock_word */, } } -void AbslInternalSpinLockWake(std::atomic* /* lock_word */, - bool /* all */) {} +void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)( + std::atomic* /* lock_word */, bool /* all */) {} } // extern "C" diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 7024e54e..5a29bed7 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -181,7 +181,9 @@ static bool ShouldForceSampling() { if (ABSL_PREDICT_TRUE(state == kDontForce)) return false; if (state == kUninitialized) { - state = AbslContainerInternalSampleEverything() ? kForce : kDontForce; + state = ABSL_INTERNAL_C_SYMBOL(AbslContainerInternalSampleEverything)() + ? kForce + : kDontForce; global_state.store(state, std::memory_order_relaxed); } return state == kForce; diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index 65d3fb5b..85685f72 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -313,7 +313,7 @@ void SetHashtablezMaxSamples(int32_t max); // initialization of static storage duration objects. // The definition of this constant is weak, which allows us to inject a // different value for it at link time. -extern "C" bool AbslContainerInternalSampleEverything(); +extern "C" bool ABSL_INTERNAL_C_SYMBOL(AbslContainerInternalSampleEverything)(); } // namespace container_internal ABSL_NAMESPACE_END diff --git a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc index 78b9d362..ed35a7ee 100644 --- a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc +++ b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc @@ -21,7 +21,8 @@ ABSL_NAMESPACE_BEGIN namespace container_internal { // See hashtablez_sampler.h for details. -extern "C" ABSL_ATTRIBUTE_WEAK bool AbslContainerInternalSampleEverything() { +extern "C" ABSL_ATTRIBUTE_WEAK bool ABSL_INTERNAL_C_SYMBOL( + AbslContainerInternalSampleEverything)() { return false; } diff --git a/absl/flags/usage_config.cc b/absl/flags/usage_config.cc index ae2f548a..5d7426db 100644 --- a/absl/flags/usage_config.cc +++ b/absl/flags/usage_config.cc @@ -34,7 +34,8 @@ extern "C" { // Additional report of fatal usage error message before we std::exit. Error is // fatal if is_fatal argument to ReportUsageError is true. -ABSL_ATTRIBUTE_WEAK void AbslInternalReportFatalUsageError(absl::string_view) {} +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL( + AbslInternalReportFatalUsageError)(absl::string_view) {} } // extern "C" @@ -128,7 +129,7 @@ void ReportUsageError(absl::string_view msg, bool is_fatal) { std::cerr << "ERROR: " << msg << std::endl; if (is_fatal) { - AbslInternalReportFatalUsageError(msg); + ABSL_INTERNAL_C_SYMBOL(AbslInternalReportFatalUsageError)(msg); } } diff --git a/absl/flags/usage_config.h b/absl/flags/usage_config.h index 96eecea2..ded70300 100644 --- a/absl/flags/usage_config.h +++ b/absl/flags/usage_config.h @@ -127,7 +127,8 @@ extern "C" { // Additional report of fatal usage error message before we std::exit. Error is // fatal if is_fatal argument to ReportUsageError is true. -void AbslInternalReportFatalUsageError(absl::string_view); +void ABSL_INTERNAL_C_SYMBOL(AbslInternalReportFatalUsageError)( + absl::string_view); } // extern "C" diff --git a/absl/random/internal/mock_helpers.h b/absl/random/internal/mock_helpers.h index 9af27ab3..a412ff2f 100644 --- a/absl/random/internal/mock_helpers.h +++ b/absl/random/internal/mock_helpers.h @@ -80,6 +80,13 @@ class MockHelpers { } public: + // InvokeMock is private; this provides access for some specialized use cases. + template + static inline bool PrivateInvokeMock(URBG* urbg, IdType type, + void* args_tuple, void* result) { + return urbg->InvokeMock(type, args_tuple, result); + } + // Invoke a mock for the KeyT (may or may not be a signature). // // KeyT is used to generate a typeid-based lookup key for the mock. @@ -109,11 +116,11 @@ class MockHelpers { // The mocked function signature will be composed from KeyT as: // result_type(args...) template - static auto MockFor(MockURBG& m) -> decltype( - std::declval() - .template RegisterMock::result_type, - typename KeySignature::arg_tuple_type>( - std::declval())) { + static auto MockFor(MockURBG& m) + -> decltype(m.template RegisterMock< + typename KeySignature::result_type, + typename KeySignature::arg_tuple_type>( + std::declval())) { return m.template RegisterMock::result_type, typename KeySignature::arg_tuple_type>( ::absl::base_internal::FastTypeId()); diff --git a/absl/synchronization/internal/per_thread_sem.cc b/absl/synchronization/internal/per_thread_sem.cc index 821ca9b4..a6031787 100644 --- a/absl/synchronization/internal/per_thread_sem.cc +++ b/absl/synchronization/internal/per_thread_sem.cc @@ -68,12 +68,12 @@ ABSL_NAMESPACE_END extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalPerThreadSemPost( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPost)( absl::base_internal::ThreadIdentity *identity) { absl::synchronization_internal::Waiter::GetWaiter(identity)->Post(); } -ABSL_ATTRIBUTE_WEAK bool AbslInternalPerThreadSemWait( +ABSL_ATTRIBUTE_WEAK bool ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)( absl::synchronization_internal::KernelTimeout t) { bool timeout = false; absl::base_internal::ThreadIdentity *identity; diff --git a/absl/synchronization/internal/per_thread_sem.h b/absl/synchronization/internal/per_thread_sem.h index 2228b6e8..7beae8ef 100644 --- a/absl/synchronization/internal/per_thread_sem.h +++ b/absl/synchronization/internal/per_thread_sem.h @@ -96,20 +96,20 @@ ABSL_NAMESPACE_END // By changing our extension points to be extern "C", we dodge this // check. extern "C" { -void AbslInternalPerThreadSemPost( +void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPost)( absl::base_internal::ThreadIdentity* identity); -bool AbslInternalPerThreadSemWait( +bool ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)( absl::synchronization_internal::KernelTimeout t); } // extern "C" void absl::synchronization_internal::PerThreadSem::Post( absl::base_internal::ThreadIdentity* identity) { - AbslInternalPerThreadSemPost(identity); + ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPost)(identity); } bool absl::synchronization_internal::PerThreadSem::Wait( absl::synchronization_internal::KernelTimeout t) { - return AbslInternalPerThreadSemWait(t); + return ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)(t); } #endif // ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_ diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index 7e66a7d0..30264a3c 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc @@ -70,7 +70,9 @@ using absl::synchronization_internal::KernelTimeout; using absl::synchronization_internal::PerThreadSem; extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalMutexYield() { std::this_thread::yield(); } +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)() { + std::this_thread::yield(); +} } // extern "C" namespace absl { @@ -170,7 +172,7 @@ int MutexDelay(int32_t c, int mode) { ABSL_TSAN_MUTEX_PRE_DIVERT(nullptr, 0); if (c == limit) { // Yield once. - AbslInternalMutexYield(); + ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)(); c++; } else { // Then wait. diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 8c6d573d..73c5bf50 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -1078,7 +1078,7 @@ ABSL_NAMESPACE_END // By changing our extension points to be extern "C", we dodge this // check. extern "C" { -void AbslInternalMutexYield(); +void ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)(); } // extern "C" #endif // ABSL_SYNCHRONIZATION_MUTEX_H_ diff --git a/absl/time/clock.cc b/absl/time/clock.cc index c61dcc03..7b204c4e 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc @@ -573,7 +573,8 @@ ABSL_NAMESPACE_END extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalSleepFor(absl::Duration duration) { +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)( + absl::Duration duration) { while (duration > absl::ZeroDuration()) { absl::Duration to_sleep = std::min(duration, absl::MaxSleep()); absl::SleepOnce(to_sleep); diff --git a/absl/time/clock.h b/absl/time/clock.h index 27764a92..5fe244d6 100644 --- a/absl/time/clock.h +++ b/absl/time/clock.h @@ -64,11 +64,11 @@ ABSL_NAMESPACE_END // By changing our extension points to be extern "C", we dodge this // check. extern "C" { -void AbslInternalSleepFor(absl::Duration duration); +void ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)(absl::Duration duration); } // extern "C" inline void absl::SleepFor(absl::Duration duration) { - AbslInternalSleepFor(duration); + ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)(duration); } #endif // ABSL_TIME_CLOCK_H_ -- cgit v1.2.3