Export of internal Abseil changes.

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

Fix test string with embedded NUL. Currently parses as octal.

PiperOrigin-RevId: 237088193

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

Make symbolizer examine any mapping with read+exec permission regardless of 'w' bit.

PiperOrigin-RevId: 237056461

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

Switch comments referencing base:: CondVar and Mutex to absl::.

PiperOrigin-RevId: 236917884

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

Internal change

PiperOrigin-RevId: 236898300

--
3cdc82429af964846d1152f49148abc61d196a4b by Samuel Benzaquen <sbenza@google.com>:

Make the `long double` overload if AbslHashValue a template to avoid invalid
conversions with implicit operators.

This overload was never meant to capture anything other than `long double` and any current caller to it that wasn't a `long double` is potentially a bug.
In particular, any type with an implicit `bool` conversion is calling this
overload instead of trying to find a hash<> specialization, thus causing
pretty bad hash behavior.

PiperOrigin-RevId: 236877073
GitOrigin-RevId: f9f068aa8a260dc576398e47b8e4540902e41358
Change-Id: If9cc008dd814f0ca06ed881f612c06575f1f7137
This commit is contained in:
Abseil Team 2019-03-06 11:36:55 -08:00 committed by Derek Mauro
parent 9fdf5e5b80
commit febc5ee6a9
70 changed files with 483 additions and 410 deletions

View file

@ -279,7 +279,8 @@ void TestHalfwayValue(const std::string& mantissa, int exponent,
absl::from_chars(low_rep.data(), low_rep.data() + low_rep.size(), actual_low);
EXPECT_EQ(expected_low, actual_low);
std::string high_rep = absl::StrCat(mantissa, std::string(1000, '0'), "1e", exponent);
std::string high_rep =
absl::StrCat(mantissa, std::string(1000, '0'), "1e", exponent);
FloatType actual_high = 0;
absl::from_chars(high_rep.data(), high_rep.data() + high_rep.size(),
actual_high);

View file

@ -179,7 +179,8 @@ bool CUnescapeInternal(absl::string_view source, bool leave_nulls_escaped,
ch = (ch << 4) + hex_digit_to_int(*++p);
if (ch > 0xFF) {
if (error) {
*error = "Value of \\" + std::string(hex_start, p + 1 - hex_start) +
*error = "Value of \\" +
std::string(hex_start, p + 1 - hex_start) +
" exceeds 0xff";
}
return false;
@ -294,7 +295,7 @@ bool CUnescapeInternal(absl::string_view source, bool leave_nulls_escaped,
// ----------------------------------------------------------------------
// CUnescapeInternal()
//
// Same as above but uses a C++ string for output. 'source' and 'dest'
// Same as above but uses a std::string for output. 'source' and 'dest'
// may be the same.
// ----------------------------------------------------------------------
bool CUnescapeInternal(absl::string_view source, bool leave_nulls_escaped,
@ -324,7 +325,8 @@ bool CUnescapeInternal(absl::string_view source, bool leave_nulls_escaped,
//
// Escaped chars: \n, \r, \t, ", ', \, and !absl::ascii_isprint().
// ----------------------------------------------------------------------
std::string CEscapeInternal(absl::string_view src, bool use_hex, bool utf8_safe) {
std::string CEscapeInternal(absl::string_view src, bool use_hex,
bool utf8_safe) {
std::string dest;
bool last_hex_escape = false; // true if last output char was \xNN.
@ -1011,7 +1013,8 @@ 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 string.
// This is a templated function so that T can be either a char* or a
// std::string.
template <typename T>
void BytesToHexStringInternal(const unsigned char* src, T dest, ptrdiff_t num) {
auto dest_ptr = &dest[0];
@ -1028,7 +1031,8 @@ void BytesToHexStringInternal(const unsigned char* src, T dest, ptrdiff_t num) {
//
// See CUnescapeInternal() for implementation details.
// ----------------------------------------------------------------------
bool CUnescape(absl::string_view source, std::string* dest, std::string* error) {
bool CUnescape(absl::string_view source, std::string* dest,
std::string* error) {
return CUnescapeInternal(source, kUnescapeNulls, dest, error);
}

View file

@ -36,18 +36,19 @@ struct epair {
TEST(CEscape, EscapeAndUnescape) {
const std::string inputs[] = {
std::string("foo\nxx\r\b\0023"),
std::string(""),
std::string("abc"),
std::string("\1chad_rules"),
std::string("\1arnar_drools"),
std::string("xxxx\r\t'\"\\"),
std::string("\0xx\0", 4),
std::string("\x01\x31"),
std::string("abc\xb\x42\141bc"),
std::string("123\1\x31\x32\x33"),
std::string("\xc1\xca\x1b\x62\x19o\xcc\x04"),
std::string("\\\"\xe8\xb0\xb7\xe6\xad\x8c\\\" is Google\\\'s Chinese name"),
std::string("foo\nxx\r\b\0023"),
std::string(""),
std::string("abc"),
std::string("\1chad_rules"),
std::string("\1arnar_drools"),
std::string("xxxx\r\t'\"\\"),
std::string("\0xx\0", 4),
std::string("\x01\x31"),
std::string("abc\xb\x42\141bc"),
std::string("123\1\x31\x32\x33"),
std::string("\xc1\xca\x1b\x62\x19o\xcc\x04"),
std::string(
"\\\"\xe8\xb0\xb7\xe6\xad\x8c\\\" is Google\\\'s Chinese name"),
};
// Do this twice, once for octal escapes and once for hex escapes.
for (int kind = 0; kind < 4; kind++) {
@ -159,15 +160,14 @@ TEST(Unescape, BasicFunction) {
EXPECT_TRUE(absl::CUnescape(val.escaped, &out));
EXPECT_EQ(out, val.unescaped);
}
std::string bad[] =
{"\\u1", // too short
"\\U1", // too short
"\\Uffffff", // exceeds 0x10ffff (largest Unicode)
"\\U00110000", // exceeds 0x10ffff (largest Unicode)
"\\uD835", // surrogate character (D800-DFFF)
"\\U0000DD04", // surrogate character (D800-DFFF)
"\\777", // exceeds 0xff
"\\xABCD"}; // exceeds 0xff
std::string bad[] = {"\\u1", // too short
"\\U1", // too short
"\\Uffffff", // exceeds 0x10ffff (largest Unicode)
"\\U00110000", // exceeds 0x10ffff (largest Unicode)
"\\uD835", // surrogate character (D800-DFFF)
"\\U0000DD04", // surrogate character (D800-DFFF)
"\\777", // exceeds 0xff
"\\xABCD"}; // exceeds 0xff
for (const std::string& e : bad) {
std::string error;
std::string out;
@ -258,9 +258,11 @@ TEST_F(CUnescapeTest, UnescapesMultipleOctalNulls) {
// All escapes, including newlines and null escapes, should have been
// converted to the equivalent characters.
EXPECT_EQ(std::string("\0\n"
"0\n"
"\0\n"
"\0", 7), result_string_);
"0\n"
"\0\n"
"\0",
7),
result_string_);
}
@ -268,17 +270,21 @@ TEST_F(CUnescapeTest, UnescapesMultipleHexNulls) {
std::string original_string(kStringWithMultipleHexNulls);
EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
EXPECT_EQ(std::string("\0\n"
"0\n"
"\0\n"
"\0", 7), result_string_);
"0\n"
"\0\n"
"\0",
7),
result_string_);
}
TEST_F(CUnescapeTest, UnescapesMultipleUnicodeNulls) {
std::string original_string(kStringWithMultipleUnicodeNulls);
EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
EXPECT_EQ(std::string("\0\n"
"0\n"
"\0", 5), result_string_);
"0\n"
"\0",
5),
result_string_);
}
static struct {

View file

@ -25,18 +25,18 @@
namespace absl {
namespace strings_internal {
// The same as std::ostringstream but appends to a user-specified string,
// The same as std::ostringstream but appends to a user-specified std::string,
// and is faster. It is ~70% faster to create, ~50% faster to write to, and
// completely free to extract the result string.
// completely free to extract the result std::string.
//
// string s;
// std::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.
//
// string s;
// std::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.
//
// string s;
// std::string s;
// OStringStream(&s) << 42;
// OStringStream(&s) << ' ';
// OStringStream(&s) << 3.14;
//
// Creates a single instance of OStringStream and reuses it: fast.
//
// string s;
// std::string s;
// OStringStream strm(&s);
// strm << 42;
// strm << ' ';
@ -64,8 +64,8 @@ class OStringStream : private std::basic_streambuf<char>, public std::ostream {
// The argument can be null, in which case you'll need to call str(p) with a
// non-null argument before you can write to the stream.
//
// The destructor of OStringStream doesn't use the std::string. It's OK to destroy
// the std::string before the stream.
// The destructor of OStringStream doesn't use the std::string. It's OK to
// destroy the std::string before the stream.
explicit OStringStream(std::string* s) : std::ostream(this), s_(s) {}
std::string* str() { return s_; }

View file

@ -47,8 +47,8 @@ struct ResizeUninitializedTraits<
}
};
// Returns true if the string implementation supports a resize where
// the new characters added to the string are left untouched.
// Returns true if the std::string implementation supports a resize where
// the new characters added to the std::string are left untouched.
//
// (A better name might be "STLStringSupportsUninitializedResize", alluding to
// the previous function.)
@ -60,7 +60,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 string with known data. Uses a Google extension to ::string.
// store of the std::string with known data.
template <typename string_type, typename = void>
inline void STLStringResizeUninitialized(string_type* s, size_t new_size) {
ResizeUninitializedTraits<string_type>::Resize(s, new_size);

View file

@ -54,7 +54,8 @@ ConvertResult<Conv::p> FormatConvertImpl(VoidPtr v, ConversionSpec conv,
FormatSinkImpl* sink);
// Strings.
ConvertResult<Conv::s> FormatConvertImpl(const std::string& v, ConversionSpec conv,
ConvertResult<Conv::s> FormatConvertImpl(const std::string& v,
ConversionSpec conv,
FormatSinkImpl* sink);
ConvertResult<Conv::s> FormatConvertImpl(string_view v, ConversionSpec conv,
FormatSinkImpl* sink);
@ -409,7 +410,7 @@ class FormatArgImpl {
ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(double, __VA_ARGS__); \
ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(long double, __VA_ARGS__); \
ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(const char*, __VA_ARGS__); \
ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(std::string, __VA_ARGS__); \
ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(std::string, __VA_ARGS__); \
ABSL_INTERNAL_FORMAT_DISPATCH_INSTANTIATE_(string_view, __VA_ARGS__)
ABSL_INTERNAL_FORMAT_DISPATCH_OVERLOADS_EXPAND_(extern);

View file

@ -160,7 +160,7 @@ bool BindWithPack(const UnboundConversion* props,
}
std::string Summarize(const UntypedFormatSpecImpl format,
absl::Span<const FormatArgImpl> args) {
absl::Span<const FormatArgImpl> args) {
typedef SummarizingConverter Converter;
std::string out;
{
@ -188,7 +188,7 @@ std::ostream& Streamable::Print(std::ostream& os) const {
}
std::string& AppendPack(std::string* out, const UntypedFormatSpecImpl format,
absl::Span<const FormatArgImpl> args) {
absl::Span<const FormatArgImpl> args) {
size_t orig = out->size();
if (ABSL_PREDICT_FALSE(!FormatUntyped(out, format, args))) {
out->erase(orig);

View file

@ -153,7 +153,7 @@ class Streamable {
// for testing
std::string Summarize(UntypedFormatSpecImpl format,
absl::Span<const FormatArgImpl> args);
absl::Span<const FormatArgImpl> args);
bool BindWithPack(const UnboundConversion* props,
absl::Span<const FormatArgImpl> pack, BoundConversion* bound);
@ -162,10 +162,10 @@ bool FormatUntyped(FormatRawSinkImpl raw_sink,
absl::Span<const FormatArgImpl> args);
std::string& AppendPack(std::string* out, UntypedFormatSpecImpl format,
absl::Span<const FormatArgImpl> args);
absl::Span<const FormatArgImpl> args);
inline std::string FormatPack(const UntypedFormatSpecImpl format,
absl::Span<const FormatArgImpl> args) {
absl::Span<const FormatArgImpl> args) {
std::string out;
AppendPack(&out, format, args);
return out;
@ -176,7 +176,7 @@ int FprintF(std::FILE* output, UntypedFormatSpecImpl format,
int SnprintF(char* output, size_t size, UntypedFormatSpecImpl format,
absl::Span<const FormatArgImpl> args);
// Returned by Streamed(v). Converts via '%s' to the string created
// Returned by Streamed(v). Converts via '%s' to the std::string created
// by std::ostream << v.
template <typename T>
class StreamedWrapper {

View file

@ -62,32 +62,32 @@ TEST(StrFormatChecker, ValidFormat) {
ValidFormat<int>("%% %d"), //
ValidFormat<int>("%ld"), //
ValidFormat<int>("%lld"), //
ValidFormat<std::string>("%s"), //
ValidFormat<std::string>("%10s"), //
ValidFormat<std::string>("%s"), //
ValidFormat<std::string>("%10s"), //
ValidFormat<int>("%.10x"), //
ValidFormat<int, int>("%*.3x"), //
ValidFormat<int>("%1.d"), //
ValidFormat<int>("%.d"), //
ValidFormat<int, double>("%d %g"), //
ValidFormat<int, std::string>("%*s"), //
ValidFormat<int, std::string>("%*s"), //
ValidFormat<int, double>("%.*f"), //
ValidFormat<void (*)(), volatile int*>("%p %p"), //
ValidFormat<string_view, const char*, double, void*>(
"string_view=%s const char*=%s double=%f void*=%p)"),
ValidFormat<int>("%% %1$d"), //
ValidFormat<int>("%1$ld"), //
ValidFormat<int>("%1$lld"), //
ValidFormat<std::string>("%1$s"), //
ValidFormat<std::string>("%1$10s"), //
ValidFormat<int>("%1$.10x"), //
ValidFormat<int>("%1$*1$.*1$d"), //
ValidFormat<int, int>("%1$*2$.3x"), //
ValidFormat<int>("%1$1.d"), //
ValidFormat<int>("%1$.d"), //
ValidFormat<double, int>("%2$d %1$g"), //
ValidFormat<int, std::string>("%2$*1$s"), //
ValidFormat<int, double>("%2$.*1$f"), //
ValidFormat<int>("%% %1$d"), //
ValidFormat<int>("%1$ld"), //
ValidFormat<int>("%1$lld"), //
ValidFormat<std::string>("%1$s"), //
ValidFormat<std::string>("%1$10s"), //
ValidFormat<int>("%1$.10x"), //
ValidFormat<int>("%1$*1$.*1$d"), //
ValidFormat<int, int>("%1$*2$.3x"), //
ValidFormat<int>("%1$1.d"), //
ValidFormat<int>("%1$.d"), //
ValidFormat<double, int>("%2$d %1$g"), //
ValidFormat<int, std::string>("%2$*1$s"), //
ValidFormat<int, double>("%2$.*1$f"), //
ValidFormat<void*, string_view, const char*, double>(
"string_view=%2$s const char*=%3$s double=%4$f void*=%1$p "
"repeat=%3$s)")};
@ -99,25 +99,25 @@ TEST(StrFormatChecker, ValidFormat) {
constexpr Case falses[] = {
ValidFormat<int>(""), //
ValidFormat<e>("%s"), //
ValidFormat<e2>("%s"), //
ValidFormat<>("%s"), //
ValidFormat<>("%r"), //
ValidFormat<int>("%s"), //
ValidFormat<int>("%.1.d"), //
ValidFormat<int>("%*1d"), //
ValidFormat<int>("%1-d"), //
ValidFormat<e>("%s"), //
ValidFormat<e2>("%s"), //
ValidFormat<>("%s"), //
ValidFormat<>("%r"), //
ValidFormat<int>("%s"), //
ValidFormat<int>("%.1.d"), //
ValidFormat<int>("%*1d"), //
ValidFormat<int>("%1-d"), //
ValidFormat<std::string, int>("%*s"), //
ValidFormat<int>("%*d"), //
ValidFormat<int>("%*d"), //
ValidFormat<std::string>("%p"), //
ValidFormat<int (*)(int)>("%d"), //
ValidFormat<int (*)(int)>("%d"), //
ValidFormat<>("%3$d"), //
ValidFormat<>("%1$r"), //
ValidFormat<int>("%1$s"), //
ValidFormat<int>("%1$.1.d"), //
ValidFormat<int>("%1$*2$1d"), //
ValidFormat<int>("%1$1-d"), //
ValidFormat<>("%3$d"), //
ValidFormat<>("%1$r"), //
ValidFormat<int>("%1$s"), //
ValidFormat<int>("%1$.1.d"), //
ValidFormat<int>("%1$*2$1d"), //
ValidFormat<int>("%1$1-d"), //
ValidFormat<std::string, int>("%2$*1$s"), //
ValidFormat<std::string>("%1$p"),

View file

@ -360,7 +360,7 @@ enum class Conv : uint64_t {
integral = d | i | u | o | x | X,
floating = a | e | f | g | A | E | F | G,
numeric = integral | floating,
string = s, // absl:ignore(std::string)
string = s,
pointer = p
};

View file

@ -28,12 +28,6 @@ TEST(InvokeFlush, String) {
std::string str = "ABC";
str_format_internal::InvokeFlush(&str, "DEF");
EXPECT_EQ(str, "ABCDEF");
#if UTIL_FORMAT_HAS_GLOBAL_STRING
std::string str2 = "ABC";
str_format_internal::InvokeFlush(&str2, "DEF");
EXPECT_EQ(str2, "ABCDEF");
#endif // UTIL_FORMAT_HAS_GLOBAL_STRING
}
TEST(InvokeFlush, Stream) {

View file

@ -193,7 +193,7 @@ struct DefaultFormatter<std::unique_ptr<ValueType>>
// and formats each element using the provided Formatter object.
template <typename Iterator, typename Formatter>
std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s,
Formatter&& f) {
Formatter&& f) {
std::string result;
absl::string_view sep("");
for (Iterator it = start; it != end; ++it) {
@ -212,7 +212,7 @@ std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s,
// 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 string-like objects (e.g., string, absl::string_view), and an
// range of string-like objects (e.g., std::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
@ -224,7 +224,7 @@ template <typename Iterator,
typename std::iterator_traits<Iterator>::iterator_category,
std::forward_iterator_tag>::value>::type>
std::string JoinAlgorithm(Iterator start, Iterator end, absl::string_view s,
NoFormatter) {
NoFormatter) {
std::string result;
if (start != end) {
// Sums size
@ -276,14 +276,15 @@ struct JoinTupleLoop<N, N> {
template <typename... T, typename Formatter>
std::string JoinAlgorithm(const std::tuple<T...>& tup, absl::string_view sep,
Formatter&& fmt) {
Formatter&& fmt) {
std::string result;
JoinTupleLoop<0, sizeof...(T)>()(&result, tup, sep, fmt);
return result;
}
template <typename Iterator>
std::string JoinRange(Iterator first, Iterator last, absl::string_view separator) {
std::string JoinRange(Iterator first, Iterator last,
absl::string_view separator) {
// No formatter was explicitly given, so a default must be chosen.
typedef typename std::iterator_traits<Iterator>::value_type ValueType;
typedef typename DefaultFormatter<ValueType>::Type Formatter;
@ -292,7 +293,7 @@ std::string JoinRange(Iterator first, Iterator last, absl::string_view separator
template <typename Range, typename Formatter>
std::string JoinRange(const Range& range, absl::string_view separator,
Formatter&& fmt) {
Formatter&& fmt) {
using std::begin;
using std::end;
return JoinAlgorithm(begin(range), end(range), separator, fmt);

View file

@ -96,8 +96,8 @@ ConvertibleToStringView(std::string&& s) // NOLINT(runtime/explicit)
}
}
// Holds the data moved from temporary std::string arguments. Declared first so
// that 'value' can refer to 'copy_'.
// Holds the data moved from temporary std::string arguments. Declared first
// so that 'value' can refer to 'copy_'.
std::string copy_;
absl::string_view value_;
};
@ -376,10 +376,10 @@ class Splitter {
// Partial specialization for a std::vector<std::string>.
//
// Optimized for the common case of splitting to a std::vector<std::string>. In
// this case we first split the results to a std::vector<absl::string_view> so
// the returned std::vector<std::string> can have space reserved to avoid std::string
// moves.
// Optimized for the common case of splitting to a std::vector<std::string>.
// In this case we first split the results to a std::vector<absl::string_view>
// so the returned std::vector<std::string> can have space reserved to avoid
// std::string moves.
template <typename A>
struct ConvertToContainer<std::vector<std::string, A>, std::string, false> {
std::vector<std::string, A> operator()(const Splitter& splitter) const {

View file

@ -29,10 +29,10 @@ namespace {
#endif
TEST(EncodeUTF8Char, BasicFunction) {
std::pair<char32_t, std::string> tests[] = {{0x0030, u8"\u0030"},
{0x00A3, u8"\u00A3"},
{0x00010000, u8"\U00010000"},
{0x0000FFFF, u8"\U0000FFFF"},
{0x0010FFFD, u8"\U0010FFFD"}};
{0x00A3, u8"\u00A3"},
{0x00010000, u8"\U00010000"},
{0x0000FFFF, u8"\U0000FFFF"},
{0x0010FFFD, u8"\U0010FFFD"}};
for (auto &test : tests) {
char buf0[7] = {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00'};
char buf1[7] = {'\xFF', '\xFF', '\xFF', '\xFF', '\xFF', '\xFF', '\xFF'};

View file

@ -19,7 +19,7 @@
namespace {
TEST(MatchTest, StartsWith) {
const std::string s1("123" "\0" "456", 7);
const std::string s1("123\0abc", 7);
const absl::string_view a("foobar");
const absl::string_view b(s1);
const absl::string_view e;
@ -36,7 +36,7 @@ TEST(MatchTest, StartsWith) {
}
TEST(MatchTest, EndsWith) {
const std::string s1("123" "\0" "456", 7);
const std::string s1("123\0abc", 7);
const absl::string_view a("foobar");
const absl::string_view b(s1);
const absl::string_view e;

View file

@ -191,7 +191,8 @@ void CheckUInt64(uint64_t x) {
EXPECT_EQ(expected, std::string(&buffer[1], actual)) << " Input " << x;
char* generic_actual = absl::numbers_internal::FastIntToBuffer(x, &buffer[1]);
EXPECT_EQ(expected, std::string(&buffer[1], generic_actual)) << " Input " << x;
EXPECT_EQ(expected, std::string(&buffer[1], generic_actual))
<< " Input " << x;
char* my_actual =
absl::numbers_internal::FastIntToBuffer(MyUInt64(x), &buffer[1]);
@ -879,8 +880,8 @@ TEST_F(SimpleDtoaTest, ExhaustiveDoubleToSixDigits) {
char buf[kSixDigitsToBufferSize];
ABSL_RAW_LOG(
INFO, "%s",
absl::StrCat("Exp ", exponent, " powten=", powten, "(",
powten, ") (",
absl::StrCat("Exp ", exponent, " powten=", powten, "(", powten,
") (",
std::string(buf, SixDigitsToBuffer(powten, buf)), ")")
.c_str());
}

View file

@ -78,7 +78,7 @@ AlphaNum::AlphaNum(Dec dec) {
// ----------------------------------------------------------------------
// StrCat()
// This merges the given strings or integers, with no delimiter. This
// This merges the given strings or integers, with no delimiter. This
// is designed to be the fastest possible way to construct a string out
// of a mix of raw C strings, string_views, strings, and integer values.
// ----------------------------------------------------------------------
@ -119,7 +119,7 @@ std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c) {
}
std::string StrCat(const AlphaNum& a, const AlphaNum& b, const AlphaNum& c,
const AlphaNum& d) {
const AlphaNum& d) {
std::string result;
strings_internal::STLStringResizeUninitialized(
&result, a.size() + b.size() + c.size() + d.size());

View file

@ -245,6 +245,7 @@ class AlphaNum {
AlphaNum(const char* c_str) : piece_(c_str) {} // NOLINT(runtime/explicit)
AlphaNum(absl::string_view pc) : piece_(pc) {} // NOLINT(runtime/explicit)
template <typename Allocator>
AlphaNum( // NOLINT(runtime/explicit)
const std::basic_string<char, std::char_traits<char>, Allocator>& str)
@ -317,16 +318,15 @@ ABSL_MUST_USE_RESULT inline std::string StrCat(const AlphaNum& a) {
ABSL_MUST_USE_RESULT std::string StrCat(const AlphaNum& a, const AlphaNum& b);
ABSL_MUST_USE_RESULT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
const AlphaNum& c);
const AlphaNum& c);
ABSL_MUST_USE_RESULT std::string StrCat(const AlphaNum& a, const AlphaNum& b,
const AlphaNum& c, const AlphaNum& d);
const AlphaNum& c, const AlphaNum& d);
// Support 5 or more arguments
template <typename... AV>
ABSL_MUST_USE_RESULT inline std::string StrCat(const AlphaNum& a, const AlphaNum& b,
const AlphaNum& c, const AlphaNum& d,
const AlphaNum& e,
const AV&... args) {
ABSL_MUST_USE_RESULT inline std::string StrCat(
const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d,
const AlphaNum& e, const AV&... args) {
return strings_internal::CatPieces(
{a.Piece(), b.Piece(), c.Piece(), d.Piece(), e.Piece(),
static_cast<const AlphaNum&>(args).Piece()...});
@ -344,18 +344,18 @@ ABSL_MUST_USE_RESULT inline std::string StrCat(const AlphaNum& a, const AlphaNum
// not try to check each of its input arguments to be sure that they are not
// a subset of the string being appended to. That is, while this will work:
//
// string s = "foo";
// std::string s = "foo";
// s += s;
//
// This output is undefined:
//
// string s = "foo";
// std::string s = "foo";
// StrAppend(&s, s);
//
// This output is undefined as well, since `absl::string_view` does not own its
// data:
//
// string s = "foobar";
// std::string s = "foobar";
// absl::string_view p = s;
// StrAppend(&s, p);

View file

@ -106,11 +106,7 @@ TEST(StrCat, Enums) {
TEST(StrCat, Basics) {
std::string result;
std::string strs[] = {
"Hello",
"Cruel",
"World"
};
std::string strs[] = {"Hello", "Cruel", "World"};
std::string stdstrs[] = {
"std::Hello",
@ -164,9 +160,10 @@ TEST(StrCat, Basics) {
result = absl::StrCat(ui64s[0], ", ", ui64s[1], "!");
EXPECT_EQ(result, "12345678910, 10987654321!");
std::string one = "1"; // Actually, it's the size of this std::string that we want; a
// 64-bit build distinguishes between size_t and uint64_t,
// even though they're both unsigned 64-bit values.
std::string one =
"1"; // Actually, it's the size of this std::string that we want; a
// 64-bit build distinguishes between size_t and uint64_t,
// even though they're both unsigned 64-bit values.
result = absl::StrCat("And a ", one.size(), " and a ",
&result[2] - &result[0], " and a ", one, " 2 3 4", "!");
EXPECT_EQ(result, "And a 1 and a 2 and a 1 2 3 4!");
@ -306,11 +303,7 @@ TEST(StrCat, MaxArgs) {
TEST(StrAppend, Basics) {
std::string result = "existing text";
std::string strs[] = {
"Hello",
"Cruel",
"World"
};
std::string strs[] = {"Hello", "Cruel", "World"};
std::string stdstrs[] = {
"std::Hello",
@ -365,9 +358,10 @@ TEST(StrAppend, Basics) {
absl::StrAppend(&result, ui64s[0], ", ", ui64s[1], "!");
EXPECT_EQ(result.substr(old_size), "12345678910, 10987654321!");
std::string one = "1"; // Actually, it's the size of this std::string that we want; a
// 64-bit build distinguishes between size_t and uint64_t,
// even though they're both unsigned 64-bit values.
std::string one =
"1"; // Actually, it's the size of this std::string that we want; a
// 64-bit build distinguishes between size_t and uint64_t,
// even though they're both unsigned 64-bit values.
old_size = result.size();
absl::StrAppend(&result, "And a ", one.size(), " and a ",
&result[2] - &result[0], " and a ", one, " 2 3 4", "!");

View file

@ -24,7 +24,8 @@
//
// Example:
//
// string s = absl::StrFormat("%s %s You have $%d!", "Hello", name, dollars);
// std::string s = absl::StrFormat(
// "%s %s You have $%d!", "Hello", name, dollars);
//
// The library consists of the following basic utilities:
//
@ -89,7 +90,7 @@ namespace absl {
// Example:
//
// absl::UntypedFormatSpec format("%d");
// string out;
// std::string out;
// CHECK(absl::FormatUntyped(&out, format, {absl::FormatArg(1)}));
class UntypedFormatSpec {
public:
@ -135,8 +136,8 @@ str_format_internal::StreamedWrapper<T> FormatStreamed(const T& v) {
// Example:
//
// int n = 0;
// string s = absl::StrFormat("%s%d%n", "hello", 123,
// absl::FormatCountCapture(&n));
// std::string s = absl::StrFormat("%s%d%n", "hello", 123,
// absl::FormatCountCapture(&n));
// EXPECT_EQ(8, n);
class FormatCountCapture {
public:
@ -223,7 +224,7 @@ class FormatCountCapture {
// "%p", *int -> "0x7ffdeb6ad2a4"
//
// int n = 0;
// string s = absl::StrFormat(
// std::string s = absl::StrFormat(
// "%s%d%n", "hello", 123, absl::FormatCountCapture(&n));
// EXPECT_EQ(8, n);
//
@ -290,14 +291,14 @@ using ParsedFormat = str_format_internal::ExtendedParsedFormat<
//
// Example:
//
// string s = absl::StrFormat(
// std::string s = absl::StrFormat(
// "Welcome to %s, Number %d!", "The Village", 6);
// EXPECT_EQ("Welcome to The Village, Number 6!", s);
//
// Returns an empty string in case of error.
template <typename... Args>
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec<Args...>& format,
const Args&... args) {
const Args&... args) {
return str_format_internal::FormatPack(
str_format_internal::UntypedFormatSpecImpl::Extract(format),
{str_format_internal::FormatArgImpl(args)...});
@ -311,11 +312,12 @@ ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec<Args...>& format,
//
// Example:
//
// string orig("For example PI is approximately ");
// std::string orig("For example PI is approximately ");
// std::cout << StrAppendFormat(&orig, "%12.6f", 3.14);
template <typename... Args>
std::string& StrAppendFormat(std::string* dst, const FormatSpec<Args...>& format,
const Args&... args) {
std::string& StrAppendFormat(std::string* dst,
const FormatSpec<Args...>& format,
const Args&... args) {
return str_format_internal::AppendPack(
dst, str_format_internal::UntypedFormatSpecImpl::Extract(format),
{str_format_internal::FormatArgImpl(args)...});
@ -434,7 +436,8 @@ class FormatRawSink {
// `absl::FormatRawSink` interface), using a format string and zero or more
// additional arguments.
//
// By default, `string` and `std::ostream` are supported as destination objects.
// By default, `std::string` and `std::ostream` are supported as destination
// objects.
//
// `absl::Format()` is a generic version of `absl::StrFormat(), for custom
// sinks. The format string, like format strings for `StrFormat()`, is checked
@ -483,9 +486,10 @@ using FormatArg = str_format_internal::FormatArgImpl;
//
// Example:
//
// std::optional<string> FormatDynamic(const string& in_format,
// const vector<string>& in_args) {
// string out;
// std::optional<std::string> FormatDynamic(
// const std::string& in_format,
// const vector<std::string>& in_args) {
// std::string out;
// std::vector<absl::FormatArg> args;
// for (const auto& v : in_args) {
// // It is important that 'v' is a reference to the objects in in_args.

View file

@ -341,7 +341,7 @@ TEST(StrFormat, BehavesAsDocumented) {
EXPECT_EQ(StrFormat("%c", int{'a'}), "a");
EXPECT_EQ(StrFormat("%c", long{'a'}), "a"); // NOLINT
EXPECT_EQ(StrFormat("%c", uint64_t{'a'}), "a");
// "s" - std::string Eg: "C" -> "C", std::string("C++") -> "C++"
// "s" - std::string Eg: "C" -> "C", std::string("C++") -> "C++"
// Formats std::string, char*, string_view, and Cord.
EXPECT_EQ(StrFormat("%s", "C"), "C");
EXPECT_EQ(StrFormat("%s", std::string("C++")), "C++");
@ -606,21 +606,21 @@ TEST_F(ParsedFormatTest, RegressionMixPositional) {
// Some codegen thunks that we can use to easily dump the generated assembly for
// different StrFormat calls.
std::string CodegenAbslStrFormatInt(int i) { // NOLINT
std::string CodegenAbslStrFormatInt(int i) { // NOLINT
return absl::StrFormat("%d", i);
}
std::string CodegenAbslStrFormatIntStringInt64(int i, const std::string& s,
int64_t i64) { // NOLINT
int64_t i64) { // NOLINT
return absl::StrFormat("%d %s %d", i, s, i64);
}
void CodegenAbslStrAppendFormatInt(std::string* out, int i) { // NOLINT
void CodegenAbslStrAppendFormatInt(std::string* out, int i) { // NOLINT
absl::StrAppendFormat(out, "%d", i);
}
void CodegenAbslStrAppendFormatIntStringInt64(std::string* out, int i,
const std::string& s,
int64_t i64) { // NOLINT
const std::string& s,
int64_t i64) { // NOLINT
absl::StrAppendFormat(out, "%d %s %d", i, s, i64);
}

View file

@ -18,13 +18,13 @@
// -----------------------------------------------------------------------------
//
// This header file contains functions for joining a range of elements and
// 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
// 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.
// returning the result as a std::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 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.
//
// Ranges are specified by passing a container with `std::begin()` and
// `std::end()` iterators, container-specific `begin()` and `end()` iterators, a
@ -37,8 +37,8 @@
//
// Example:
//
// std::vector<string> v = {"foo", "bar", "baz"};
// string s = absl::StrJoin(v, "-");
// std::vector<std::string> v = {"foo", "bar", "baz"};
// std::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 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.
// argument as a string and appending it to a given output std::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 string.
// `std::to_string()` to format an integer as a std::string.
//
// struct MyFormatter {
// void operator()(string* out, int i) const {
// void operator()(std::string* out, int i) const {
// out->append(std::to_string(i));
// }
// };
@ -84,7 +84,7 @@ namespace absl {
// argument to `absl::StrJoin()`:
//
// std::vector<int> v = {1, 2, 3, 4};
// string s = absl::StrJoin(v, "-", MyFormatter());
// std::string s = absl::StrJoin(v, "-", MyFormatter());
// EXPECT_EQ("1-2-3-4", s);
//
// The following standard formatters are provided within this file:
@ -156,7 +156,7 @@ DereferenceFormatter() {
// StrJoin()
// -----------------------------------------------------------------------------
//
// Joins a range of elements and returns the result as a string.
// Joins a range of elements and returns the result as a std::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 string.
@ -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<string> v = {"foo", "bar", "baz"};
// string s = absl::StrJoin(v, "-");
// std::vector<std::string> v = {"foo", "bar", "baz"};
// std::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.
// string s = absl::StrJoin({"foo", "bar", "baz"}, "-");
// std::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<int> v = {1, 2, 3, -4};
// string s = absl::StrJoin(v, "-");
// std::string s = absl::StrJoin(v, "-");
// EXPECT_EQ("1-2-3--4", s);
//
// Example 4:
@ -193,7 +193,7 @@ DereferenceFormatter() {
// // `std::vector<int*>`.
// int x = 1, y = 2, z = 3;
// std::vector<int*> v = {&x, &y, &z};
// string s = absl::StrJoin(v, "-");
// std::string s = absl::StrJoin(v, "-");
// EXPECT_EQ("1-2-3", s);
//
// Example 5:
@ -202,53 +202,53 @@ DereferenceFormatter() {
// v.emplace_back(new int(1));
// v.emplace_back(new int(2));
// v.emplace_back(new int(3));
// string s = absl::StrJoin(v, "-");
// std::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::pair<>>`.
// std::map<string, int> m = {
// std::map<std::string, int> m = {
// std::make_pair("a", 1),
// std::make_pair("b", 2),
// std::make_pair("c", 3)};
// string s = absl::StrJoin(m, ",", absl::PairFormatter("="));
// std::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<string> v_empty;
// std::vector<std::string> v_empty;
// EXPECT_EQ("", absl::StrJoin(v_empty, "-"));
//
// std::vector<string> v_one_item = {"foo"};
// std::vector<std::string> v_one_item = {"foo"};
// EXPECT_EQ("foo", absl::StrJoin(v_one_item, "-"));
//
// std::vector<string> v_empty_string = {""};
// std::vector<std::string> v_empty_string = {""};
// EXPECT_EQ("", absl::StrJoin(v_empty_string, "-"));
//
// std::vector<string> v_one_item_empty_string = {"a", ""};
// std::vector<std::string> v_one_item_empty_string = {"a", ""};
// EXPECT_EQ("a-", absl::StrJoin(v_one_item_empty_string, "-"));
//
// std::vector<string> v_two_empty_string = {"", ""};
// std::vector<std::string> v_two_empty_string = {"", ""};
// EXPECT_EQ("-", absl::StrJoin(v_two_empty_string, "-"));
//
// Example 8:
// // Joins a `std::tuple<T...>` of heterogeneous types, converting each to
// // a string using the `absl::AlphaNum` class.
// string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-");
// // a std::string using the `absl::AlphaNum` class.
// std::string s = absl::StrJoin(std::make_tuple(123, "abc", 0.456), "-");
// EXPECT_EQ("123-abc-0.456", s);
template <typename Iterator, typename Formatter>
std::string StrJoin(Iterator start, Iterator end, absl::string_view sep,
Formatter&& fmt) {
Formatter&& fmt) {
return strings_internal::JoinAlgorithm(start, end, sep, fmt);
}
template <typename Range, typename Formatter>
std::string StrJoin(const Range& range, absl::string_view separator,
Formatter&& fmt) {
Formatter&& fmt) {
return strings_internal::JoinRange(range, separator, fmt);
}
@ -260,7 +260,7 @@ std::string StrJoin(std::initializer_list<T> il, absl::string_view separator,
template <typename... T, typename Formatter>
std::string StrJoin(const std::tuple<T...>& value, absl::string_view separator,
Formatter&& fmt) {
Formatter&& fmt) {
return strings_internal::JoinAlgorithm(value, separator, fmt);
}
@ -280,7 +280,8 @@ std::string StrJoin(std::initializer_list<T> il, absl::string_view separator) {
}
template <typename... T>
std::string StrJoin(const std::tuple<T...>& value, absl::string_view separator) {
std::string StrJoin(const std::tuple<T...>& value,
absl::string_view separator) {
return strings_internal::JoinAlgorithm(value, separator, AlphaNumFormatter());
}

View file

@ -58,7 +58,8 @@ void BM_Join2_KeysAndValues(benchmark::State& state) {
const int string_len = state.range(0);
const int num_pairs = state.range(1);
const std::string s(string_len, 'x');
const std::vector<std::pair<std::string, int>> v(num_pairs, std::make_pair(s, 42));
const std::vector<std::pair<std::string, int>> v(num_pairs,
std::make_pair(s, 42));
for (auto _ : state) {
std::string s = absl::StrJoin(v, ",", absl::PairFormatter("="));
benchmark::DoNotOptimize(s);

View file

@ -118,7 +118,7 @@ TEST(StrJoin, APIExamples) {
{
// A std::map, which is a collection of std::pair<>s.
std::map<std::string, int> m = { {"a", 1}, {"b", 2}, {"c", 3} };
std::map<std::string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}};
EXPECT_EQ("a=1,b=2,c=3", absl::StrJoin(m, ",", absl::PairFormatter("=")));
}
@ -140,7 +140,8 @@ TEST(StrJoin, APIExamples) {
}
{
// A range of 1 element gives a std::string with that element but no separator.
// A range of 1 element gives a std::string with that element but no
// separator.
std::vector<std::string> v = {"foo"};
EXPECT_EQ("foo", absl::StrJoin(v, "-"));
}
@ -173,9 +174,10 @@ TEST(StrJoin, APIExamples) {
TEST(StrJoin, CustomFormatter) {
std::vector<std::string> v{"One", "Two", "Three"};
{
std::string joined = absl::StrJoin(v, "", [](std::string* out, const std::string& in) {
absl::StrAppend(out, "(", in, ")");
});
std::string joined =
absl::StrJoin(v, "", [](std::string* out, const std::string& in) {
absl::StrAppend(out, "(", in, ")");
});
EXPECT_EQ("(One)(Two)(Three)", joined);
}
{

View file

@ -68,11 +68,12 @@ int ApplySubstitutions(
// aren't inlined.
std::string StrReplaceAll(absl::string_view s,
strings_internal::FixedMapping replacements) {
strings_internal::FixedMapping replacements) {
return StrReplaceAll<strings_internal::FixedMapping>(s, replacements);
}
int StrReplaceAll(strings_internal::FixedMapping replacements, std::string* target) {
int StrReplaceAll(strings_internal::FixedMapping replacements,
std::string* target) {
return StrReplaceAll<strings_internal::FixedMapping>(replacements, target);
}

View file

@ -29,12 +29,12 @@
//
// Example:
//
// string html_escaped = absl::StrReplaceAll(user_input, {
// {"&", "&amp;"},
// {"<", "&lt;"},
// {">", "&gt;"},
// {"\"", "&quot;"},
// {"'", "&#39;"}});
// std::string html_escaped = absl::StrReplaceAll(user_input, {
// {"&", "&amp;"},
// {"<", "&lt;"},
// {">", "&gt;"},
// {"\"", "&quot;"},
// {"'", "&#39;"}});
#ifndef ABSL_STRINGS_STR_REPLACE_H_
#define ABSL_STRINGS_STR_REPLACE_H_
@ -58,10 +58,11 @@ namespace absl {
//
// Example:
//
// string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!",
// {{"$count", absl::StrCat(5)},
// {"$who", "Bob"},
// {"#Noun", "Apples"}});
// std::string s = absl::StrReplaceAll(
// "$who bought $count #Noun. Thanks $who!",
// {{"$count", absl::StrCat(5)},
// {"$who", "Bob"},
// {"#Noun", "Apples"}});
// EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s);
ABSL_MUST_USE_RESULT std::string StrReplaceAll(
absl::string_view s,
@ -78,20 +79,22 @@ ABSL_MUST_USE_RESULT std::string StrReplaceAll(
// replacements["$who"] = "Bob";
// replacements["$count"] = "5";
// replacements["#Noun"] = "Apples";
// string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!",
// replacements);
// std::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<std::pair<const absl::string_view, string>> replacements;
// std::vector<std::pair<const absl::string_view, std::string>> replacements;
// replacements.push_back({"&", "&amp;"});
// replacements.push_back({"<", "&lt;"});
// replacements.push_back({">", "&gt;"});
// string s = absl::StrReplaceAll("if (ptr < &foo)",
// std::string s = absl::StrReplaceAll("if (ptr < &foo)",
// replacements);
// EXPECT_EQ("if (ptr &lt; &amp;foo)", s);
template <typename StrToStrMapping>
std::string StrReplaceAll(absl::string_view s, const StrToStrMapping& replacements);
std::string StrReplaceAll(absl::string_view s,
const StrToStrMapping& replacements);
// Overload of `StrReplaceAll()` to replace character sequences within a given
// output string *in place* with replacements provided within an initializer
@ -99,7 +102,7 @@ std::string StrReplaceAll(absl::string_view s, const StrToStrMapping& replacemen
//
// Example:
//
// string s = std::string("$who bought $count #Noun. Thanks $who!");
// std::string s = std::string("$who bought $count #Noun. Thanks $who!");
// int count;
// count = absl::StrReplaceAll({{"$count", absl::StrCat(5)},
// {"$who", "Bob"},
@ -117,7 +120,7 @@ int StrReplaceAll(
//
// Example:
//
// string s = std::string("if (ptr < &foo)");
// std::string s = std::string("if (ptr < &foo)");
// int count = absl::StrReplaceAll({{"&", "&amp;"},
// {"<", "&lt;"},
// {">", "&gt;"}}, &s);
@ -187,7 +190,8 @@ int ApplySubstitutions(absl::string_view s,
} // namespace strings_internal
template <typename StrToStrMapping>
std::string StrReplaceAll(absl::string_view s, const StrToStrMapping& replacements) {
std::string StrReplaceAll(absl::string_view s,
const StrToStrMapping& replacements) {
auto subs = strings_internal::FindSubstitutions(s, replacements);
std::string result;
result.reserve(s.size());

View file

@ -54,7 +54,7 @@ void SetUpStrings() {
size_t r = 0;
big_string = new std::string(1000 * 1000, ' ');
for (std::string phrase : {"the quick brown fox jumped over the lazy dogs",
"pack my box with the five dozen liquor jugs"}) {
"pack my box with the five dozen liquor jugs"}) {
for (int i = 0; i < 10 * 1000; ++i) {
r = r * 237 + 41; // not very random.
memcpy(&(*big_string)[r % (big_string->size() - phrase.size())],
@ -108,11 +108,11 @@ void BM_StrReplaceAll(benchmark::State& state) {
std::string src = *big_string;
for (auto _ : state) {
std::string dest = absl::StrReplaceAll(src, {{"the", "box"},
{"brown", "quick"},
{"jumped", "liquored"},
{"dozen", "brown"},
{"lazy", "pack"},
{"liquor", "shakes"}});
{"brown", "quick"},
{"jumped", "liquored"},
{"dozen", "brown"},
{"lazy", "pack"},
{"liquor", "shakes"}});
ABSL_RAW_CHECK(dest == *after_replacing_many,
"not benchmarking intended behavior");
}

View file

@ -148,7 +148,7 @@ TEST(StrReplaceAll, ManyReplacementsInMap) {
replacements["$count"] = "5";
replacements["#Noun"] = "Apples";
std::string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!",
replacements);
replacements);
EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s);
}

View file

@ -132,8 +132,7 @@ class ByString {
// ByChar
//
// A single character delimiter. `ByChar` is functionally equivalent to a
// 1-char string within a `ByString` delimiter, but slightly more
// efficient.
// 1-char string within a `ByString` delimiter, but slightly more efficient.
//
// Example:
//
@ -414,10 +413,10 @@ 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 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:
// may contain `std::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:
//
// 1) All standard STL containers including `std::vector`, `std::list`,
// `std::deque`, `std::set`,`std::multiset`, 'std::map`, and `std::multimap`
@ -461,7 +460,7 @@ struct SkipWhitespace {
// Example:
//
// // Stores first two split strings as the members in a std::pair.
// std::pair<string, string> p = absl::StrSplit("a,b,c", ',');
// std::pair<std::string, std::string> 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
@ -471,7 +470,7 @@ struct SkipWhitespace {
//
// // The input string "a=b=c,d=e,f=,g" becomes
// // { "a" => "b=c", "d" => "e", "f" => "", "g" => "" }
// std::map<string, string> m;
// std::map<std::string, std::string> m;
// for (absl::string_view sp : absl::StrSplit("a=b=c,d=e,f=,g", ',')) {
// m.insert(absl::StrSplit(sp, absl::MaxSplits('=', 1)));
// }

View file

@ -69,7 +69,8 @@ BENCHMARK_RANGE(BM_Split2String, 0, 1 << 20);
void BM_Split2SplitStringUsing(benchmark::State& state) {
std::string test = MakeTestString(state.range(0));
for (auto _ : state) {
std::vector<std::string> result = absl::StrSplit(test, ';', absl::SkipEmpty());
std::vector<std::string> result =
absl::StrSplit(test, ';', absl::SkipEmpty());
benchmark::DoNotOptimize(result);
}
}

View file

@ -40,8 +40,8 @@ using ::testing::UnorderedElementsAre;
TEST(Split, TraitsTest) {
static_assert(!absl::strings_internal::SplitterIsConvertibleTo<int>::value,
"");
static_assert(!absl::strings_internal::SplitterIsConvertibleTo<std::string>::value,
"");
static_assert(
!absl::strings_internal::SplitterIsConvertibleTo<std::string>::value, "");
static_assert(absl::strings_internal::SplitterIsConvertibleTo<
std::vector<std::string>>::value,
"");
@ -182,7 +182,8 @@ TEST(Split, APIExamples) {
{
// Uses the SkipWhitespace predicate.
using absl::SkipWhitespace;
std::vector<std::string> v = absl::StrSplit(" a , ,,b,", ',', SkipWhitespace());
std::vector<std::string> v =
absl::StrSplit(" a , ,,b,", ',', SkipWhitespace());
EXPECT_THAT(v, ElementsAre(" a ", "b"));
}
@ -215,7 +216,8 @@ TEST(Split, APIExamples) {
{
// Results stored in a std::multimap.
std::multimap<std::string, std::string> m = absl::StrSplit("a,1,b,2,a,3", ',');
std::multimap<std::string, std::string> m =
absl::StrSplit("a,1,b,2,a,3", ',');
EXPECT_EQ(3, m.size());
auto it = m.find("a");
EXPECT_EQ("1", it->second);
@ -271,7 +273,8 @@ TEST(SplitIterator, Basics) {
EXPECT_EQ("a", *it); // tests dereference
++it; // tests preincrement
EXPECT_NE(it, end);
EXPECT_EQ("b", std::string(it->data(), it->size())); // tests dereference as ptr
EXPECT_EQ("b",
std::string(it->data(), it->size())); // tests dereference as ptr
it++; // tests postincrement
EXPECT_EQ(it, end);
}
@ -295,7 +298,8 @@ TEST(SplitIterator, Predicate) {
EXPECT_EQ("a", *it); // tests dereference
++it; // tests preincrement -- "b" should be skipped here.
EXPECT_NE(it, end);
EXPECT_EQ("c", std::string(it->data(), it->size())); // tests dereference as ptr
EXPECT_EQ("c",
std::string(it->data(), it->size())); // tests dereference as ptr
it++; // tests postincrement
EXPECT_EQ(it, end);
}
@ -421,10 +425,13 @@ TEST(Splitter, ConversionOperator) {
TestMapConversionOperator<std::map<std::string, std::string>>(splitter);
TestMapConversionOperator<
std::multimap<absl::string_view, absl::string_view>>(splitter);
TestMapConversionOperator<std::multimap<absl::string_view, std::string>>(splitter);
TestMapConversionOperator<std::multimap<std::string, absl::string_view>>(splitter);
TestMapConversionOperator<std::multimap<absl::string_view, std::string>>(
splitter);
TestMapConversionOperator<std::multimap<std::string, absl::string_view>>(
splitter);
TestMapConversionOperator<std::multimap<std::string, std::string>>(splitter);
TestMapConversionOperator<std::unordered_map<std::string, std::string>>(splitter);
TestMapConversionOperator<std::unordered_map<std::string, std::string>>(
splitter);
// Tests conversion to std::pair
@ -568,10 +575,9 @@ TEST(Split, AcceptsCertainTemporaries) {
}
TEST(Split, Temporary) {
// Use a std::string longer than the small-std::string-optimization length, so that when
// the temporary is destroyed, if the splitter keeps a reference to the
// std::string's contents, it'll reference freed memory instead of just dead
// on-stack memory.
// Use a std::string longer than the SSO length, so that when the temporary is
// destroyed, if the splitter keeps a reference to the std::string's contents,
// it'll reference freed memory instead of just dead on-stack memory.
const char input[] = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u";
EXPECT_LT(sizeof(std::string), ABSL_ARRAYSIZE(input))
<< "Input should be larger than fits on the stack.";

View file

@ -277,7 +277,7 @@ class string_view {
// Checks if the `string_view` is empty (refers to no characters).
constexpr bool empty() const noexcept { return length_ == 0; }
// std::string:view::operator[]
// string_view::operator[]
//
// Returns the ith element of an `string_view` using the array operator.
// Note that this operator does not perform any bounds checking.

View file

@ -284,9 +284,10 @@ TEST(StringViewTest, ComparisonOperatorsByCharacterPosition) {
}
#undef COMPARE
// 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.
// Sadly, our users often confuse std::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.
template <typename T>
struct is_type {
@ -995,8 +996,8 @@ TEST(StringViewTest, ConstexprCompiles) {
TEST(StringViewTest, Noexcept) {
EXPECT_TRUE((std::is_nothrow_constructible<absl::string_view,
const std::string&>::value));
EXPECT_TRUE(
(std::is_nothrow_constructible<absl::string_view, const std::string&>::value));
EXPECT_TRUE((std::is_nothrow_constructible<absl::string_view,
const std::string&>::value));
EXPECT_TRUE(std::is_nothrow_constructible<absl::string_view>::value);
constexpr absl::string_view sp;
EXPECT_TRUE(noexcept(sp.begin()));

View file

@ -36,18 +36,18 @@
// use at that location within the format string.
//
// Example 1:
// string s = Substitute("$1 purchased $0 $2. Thanks $1!",
// 5, "Bob", "Apples");
// std::string s = Substitute("$1 purchased $0 $2. Thanks $1!",
// 5, "Bob", "Apples");
// EXPECT_EQ("Bob purchased 5 Apples. Thanks Bob!", s);
//
// Example 2:
// string s = "Hi. ";
// std::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, string, const char* (null is equivalent to "")
// * absl::string_view, std::string, const char* (null is equivalent to "")
// * int32_t, int64_t, uint32_t, uint64
// * float, double
// * bool (Printed as "true" or "false")
@ -456,7 +456,7 @@ void SubstituteAndAppend(
// Example:
// template <typename... Args>
// void VarMsg(absl::string_view format, const Args&... args) {
// string s = absl::Substitute(format, args...);
// std::string s = absl::Substitute(format, args...);
ABSL_MUST_USE_RESULT inline std::string Substitute(absl::string_view format) {
std::string result;
@ -574,70 +574,70 @@ std::string Substitute(const char* format, const substitute_internal::Arg& a0)
"contains one of $1-$9");
std::string Substitute(const char* format, const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1)
const substitute_internal::Arg& a1)
ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 3,
"There were 2 substitution arguments given, but "
"this format std::string is either missing its $0/$1, or "
"contains one of $2-$9");
std::string Substitute(const char* format, const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2)
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2)
ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 7,
"There were 3 substitution arguments given, but "
"this format std::string is either missing its $0/$1/$2, or "
"contains one of $3-$9");
std::string Substitute(const char* format, const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3)
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3)
ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 15,
"There were 4 substitution arguments given, but "
"this format std::string is either missing its $0-$3, or "
"contains one of $4-$9");
std::string Substitute(const char* format, const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3,
const substitute_internal::Arg& a4)
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3,
const substitute_internal::Arg& a4)
ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 31,
"There were 5 substitution arguments given, but "
"this format std::string is either missing its $0-$4, or "
"contains one of $5-$9");
std::string Substitute(const char* format, const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3,
const substitute_internal::Arg& a4,
const substitute_internal::Arg& a5)
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3,
const substitute_internal::Arg& a4,
const substitute_internal::Arg& a5)
ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 63,
"There were 6 substitution arguments given, but "
"this format std::string is either missing its $0-$5, or "
"contains one of $6-$9");
std::string Substitute(const char* format, const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3,
const substitute_internal::Arg& a4,
const substitute_internal::Arg& a5,
const substitute_internal::Arg& a6)
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3,
const substitute_internal::Arg& a4,
const substitute_internal::Arg& a5,
const substitute_internal::Arg& a6)
ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 127,
"There were 7 substitution arguments given, but "
"this format std::string is either missing its $0-$6, or "
"contains one of $7-$9");
std::string Substitute(const char* format, const substitute_internal::Arg& a0,
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3,
const substitute_internal::Arg& a4,
const substitute_internal::Arg& a5,
const substitute_internal::Arg& a6,
const substitute_internal::Arg& a7)
const substitute_internal::Arg& a1,
const substitute_internal::Arg& a2,
const substitute_internal::Arg& a3,
const substitute_internal::Arg& a4,
const substitute_internal::Arg& a5,
const substitute_internal::Arg& a6,
const substitute_internal::Arg& a7)
ABSL_BAD_CALL_IF(substitute_internal::PlaceholderBitmask(format) != 255,
"There were 8 substitution arguments given, but "
"this format std::string is either missing its $0-$7, or "