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
pull/270/head^2
Abseil Team 6 years ago committed by Derek Mauro
parent 9fdf5e5b80
commit febc5ee6a9
  1. 6
      absl/base/internal/exception_safety_testing.h
  2. 10
      absl/base/internal/raw_logging.h
  3. 4
      absl/base/internal/thread_identity.h
  4. 3
      absl/container/fixed_array_test.cc
  5. 6
      absl/container/flat_hash_map_test.cc
  6. 4
      absl/container/inlined_vector_benchmark.cc
  7. 5
      absl/container/internal/hash_function_defaults.h
  8. 8
      absl/container/internal/hash_function_defaults_test.cc
  9. 3
      absl/container/internal/layout.h
  10. 4
      absl/container/internal/raw_hash_set.h
  11. 15
      absl/container/internal/raw_hash_set_test.cc
  12. 10
      absl/container/internal/unordered_set_test.cc
  13. 3
      absl/debugging/failure_signal_handler_test.cc
  14. 7
      absl/debugging/internal/symbolize.h
  15. 16
      absl/debugging/symbolize_elf.inc
  16. 2
      absl/hash/hash.h
  17. 24
      absl/hash/hash_test.cc
  18. 4
      absl/hash/hash_testing.h
  19. 9
      absl/hash/internal/hash.h
  20. 4
      absl/hash/internal/spy_hash_state.h
  21. 3
      absl/strings/charconv_test.cc
  22. 14
      absl/strings/escaping.cc
  23. 64
      absl/strings/escaping_test.cc
  24. 16
      absl/strings/internal/ostringstream.h
  25. 6
      absl/strings/internal/resize_uninitialized.h
  26. 5
      absl/strings/internal/str_format/arg.h
  27. 4
      absl/strings/internal/str_format/bind.cc
  28. 8
      absl/strings/internal/str_format/bind.h
  29. 66
      absl/strings/internal/str_format/checker_test.cc
  30. 2
      absl/strings/internal/str_format/extension.h
  31. 6
      absl/strings/internal/str_format/output_test.cc
  32. 13
      absl/strings/internal/str_join_internal.h
  33. 12
      absl/strings/internal/str_split_internal.h
  34. 8
      absl/strings/internal/utf8_test.cc
  35. 4
      absl/strings/match_test.cc
  36. 7
      absl/strings/numbers_test.cc
  37. 4
      absl/strings/str_cat.cc
  38. 18
      absl/strings/str_cat.h
  39. 26
      absl/strings/str_cat_test.cc
  40. 32
      absl/strings/str_format.h
  41. 12
      absl/strings/str_format_test.cc
  42. 73
      absl/strings/str_join.h
  43. 3
      absl/strings/str_join_benchmark.cc
  44. 12
      absl/strings/str_join_test.cc
  45. 5
      absl/strings/str_replace.cc
  46. 40
      absl/strings/str_replace.h
  47. 12
      absl/strings/str_replace_benchmark.cc
  48. 2
      absl/strings/str_replace_test.cc
  49. 15
      absl/strings/str_split.h
  50. 3
      absl/strings/str_split_benchmark.cc
  51. 32
      absl/strings/str_split_test.cc
  52. 2
      absl/strings/string_view.h
  53. 11
      absl/strings/string_view_test.cc
  54. 66
      absl/strings/substitute.h
  55. 7
      absl/synchronization/internal/per_thread_sem_test.cc
  56. 1
      absl/time/BUILD.bazel
  57. 15
      absl/time/civil_time.cc
  58. 2
      absl/time/civil_time.h
  59. 4
      absl/time/duration.cc
  60. 1
      absl/time/duration_benchmark.cc
  61. 2
      absl/time/duration_test.cc
  62. 11
      absl/time/format.cc
  63. 7
      absl/time/format_test.cc
  64. 3
      absl/time/time.h
  65. 4
      absl/types/optional_test.cc
  66. 2
      absl/types/span.h
  67. 6
      absl/types/span_test.cc
  68. 69
      absl/types/variant_test.cc
  69. 6
      absl/utility/utility.h
  70. 2
      absl/utility/utility_test.cc

@ -169,8 +169,10 @@ class ConstructorTracker {
return current_tracker_instance_ != nullptr;
}
static std::string ErrorMessage(void* address, const std::string& address_description,
int countdown, const std::string& error_description) {
static std::string ErrorMessage(void* address,
const std::string& address_description,
int countdown,
const std::string& error_description) {
return absl::Substitute(
"With coundtown at $0:\n"
" $1\n"

@ -79,13 +79,13 @@
absl_raw_logging_internal_basename, __LINE__, message); \
} while (0)
#define ABSL_INTERNAL_CHECK(condition, message) \
do { \
if (ABSL_PREDICT_FALSE(!(condition))) { \
#define ABSL_INTERNAL_CHECK(condition, message) \
do { \
if (ABSL_PREDICT_FALSE(!(condition))) { \
std::string death_message = "Check " #condition " failed: "; \
death_message += std::string(message); \
ABSL_INTERNAL_LOG(FATAL, death_message); \
} \
ABSL_INTERNAL_LOG(FATAL, death_message); \
} \
} while (0)
#define ABSL_RAW_LOGGING_INTERNAL_INFO ::absl::LogSeverity::kInfo

@ -42,9 +42,9 @@ namespace base_internal {
class SpinLock;
struct ThreadIdentity;
// Used by the implementation of base::Mutex and base::CondVar.
// Used by the implementation of absl::Mutex and absl::CondVar.
struct PerThreadSynch {
// The internal representation of base::Mutex and base::CondVar rely
// The internal representation of absl::Mutex and absl::CondVar rely
// on the alignment of PerThreadSynch. Both store the address of the
// PerThreadSynch in the high-order bits of their internal state,
// which means the low kLowZeroBits of the address of PerThreadSynch

@ -365,7 +365,8 @@ TEST(IteratorConstructorTest, Inline) {
TEST(IteratorConstructorTest, NonPod) {
char const* kInput[] =
{ "red", "orange", "yellow", "green", "blue", "indigo", "violet" };
absl::FixedArray<std::string> const fixed(kInput, kInput + ABSL_ARRAYSIZE(kInput));
absl::FixedArray<std::string> const fixed(kInput,
kInput + ABSL_ARRAYSIZE(kInput));
ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size());
for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) {
ASSERT_EQ(kInput[i], fixed[i]);

@ -37,9 +37,9 @@ using Map = flat_hash_map<K, V, StatefulTestingHash, StatefulTestingEqual,
static_assert(!std::is_standard_layout<NonStandardLayout>(), "");
using MapTypes =
::testing::Types<Map<int, int>, Map<std::string, int>, Map<Enum, std::string>,
Map<EnumClass, int>, Map<int, NonStandardLayout>,
Map<NonStandardLayout, int>>;
::testing::Types<Map<int, int>, Map<std::string, int>,
Map<Enum, std::string>, Map<EnumClass, int>,
Map<int, NonStandardLayout>, Map<NonStandardLayout, int>>;
INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashMap, ConstructorTest, MapTypes);
INSTANTIATE_TYPED_TEST_SUITE_P(FlatHashMap, LookupTest, MapTypes);

@ -89,7 +89,7 @@ void BM_InlinedVectorFillString(benchmark::State& state) {
const int len = state.range(0);
const int no_sso = GetNonShortStringOptimizationSize();
std::string strings[4] = {std::string(no_sso, 'A'), std::string(no_sso, 'B'),
std::string(no_sso, 'C'), std::string(no_sso, 'D')};
std::string(no_sso, 'C'), std::string(no_sso, 'D')};
for (auto _ : state) {
absl::InlinedVector<std::string, 8> v;
@ -105,7 +105,7 @@ void BM_StdVectorFillString(benchmark::State& state) {
const int len = state.range(0);
const int no_sso = GetNonShortStringOptimizationSize();
std::string strings[4] = {std::string(no_sso, 'A'), std::string(no_sso, 'B'),
std::string(no_sso, 'C'), std::string(no_sso, 'D')};
std::string(no_sso, 'C'), std::string(no_sso, 'D')};
for (auto _ : state) {
std::vector<std::string> v;

@ -39,8 +39,8 @@
// equal functions are still bound to T. This is important because some type U
// can be hashed by/tested for equality differently depending on T. A notable
// example is `const char*`. `const char*` is treated as a c-style string when
// the hash function is hash<string> but as a pointer when the hash function is
// hash<void*>.
// the hash function is hash<std::string> but as a pointer when the hash
// function is hash<void*>.
//
#ifndef ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_
#define ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_
@ -83,6 +83,7 @@ struct StringHashEq {
}
};
};
template <>
struct HashEq<std::string> : StringHashEq {};
template <>

@ -202,15 +202,11 @@ TYPED_TEST(HashPointer, Works) {
EXPECT_NE(hash(&dummy), hash(cuptr));
}
// Cartesian product of (string, std::string, absl::string_view)
// with (string, std::string, absl::string_view, const char*).
// Cartesian product of (std::string, absl::string_view)
// with (std::string, absl::string_view, const char*).
using StringTypesCartesianProduct = Types<
// clang-format off
std::pair<std::string, std::string>,
std::pair<std::string, absl::string_view>,
std::pair<std::string, const char*>,
std::pair<absl::string_view, std::string>,
std::pair<absl::string_view, absl::string_view>,
std::pair<absl::string_view, const char*>>;

@ -643,7 +643,8 @@ class LayoutImpl<std::tuple<Elements...>, absl::index_sequence<SizeSeq...>,
std::string DebugString() const {
const auto offsets = Offsets();
const size_t sizes[] = {SizeOf<ElementType<OffsetSeq>>()...};
const std::string types[] = {adl_barrier::TypeName<ElementType<OffsetSeq>>()...};
const std::string types[] = {
adl_barrier::TypeName<ElementType<OffsetSeq>>()...};
std::string res = absl::StrCat("@0", types[0], "(", sizes[0], ")");
for (size_t i = 0; i != NumOffsets - 1; ++i) {
absl::StrAppend(&res, "[", size_[i], "]; @", offsets[i + 1], types[i + 1],

@ -763,8 +763,8 @@ class raw_hash_set {
// that accept std::initializer_list<T> and std::initializer_list<init_type>.
// This is advantageous for performance.
//
// // Turns {"abc", "def"} into std::initializer_list<std::string>, then copies
// // the strings into the set.
// // Turns {"abc", "def"} into std::initializer_list<std::string>, then
// // copies the strings into the set.
// std::unordered_set<std::string> s = {"abc", "def"};
//
// // Turns {"abc", "def"} into std::initializer_list<const char*>, then

@ -1460,7 +1460,8 @@ TEST(Table, MoveAssign) {
TEST(Table, Equality) {
StringTable t;
std::vector<std::pair<std::string, std::string>> v = {{"a", "b"}, {"aa", "bb"}};
std::vector<std::pair<std::string, std::string>> v = {{"a", "b"},
{"aa", "bb"}};
t.insert(std::begin(v), std::end(v));
StringTable u = t;
EXPECT_EQ(u, t);
@ -1468,20 +1469,24 @@ TEST(Table, Equality) {
TEST(Table, Equality2) {
StringTable t;
std::vector<std::pair<std::string, std::string>> v1 = {{"a", "b"}, {"aa", "bb"}};
std::vector<std::pair<std::string, std::string>> v1 = {{"a", "b"},
{"aa", "bb"}};
t.insert(std::begin(v1), std::end(v1));
StringTable u;
std::vector<std::pair<std::string, std::string>> v2 = {{"a", "a"}, {"aa", "aa"}};
std::vector<std::pair<std::string, std::string>> v2 = {{"a", "a"},
{"aa", "aa"}};
u.insert(std::begin(v2), std::end(v2));
EXPECT_NE(u, t);
}
TEST(Table, Equality3) {
StringTable t;
std::vector<std::pair<std::string, std::string>> v1 = {{"b", "b"}, {"bb", "bb"}};
std::vector<std::pair<std::string, std::string>> v1 = {{"b", "b"},
{"bb", "bb"}};
t.insert(std::begin(v1), std::end(v1));
StringTable u;
std::vector<std::pair<std::string, std::string>> v2 = {{"a", "a"}, {"aa", "aa"}};
std::vector<std::pair<std::string, std::string>> v2 = {{"a", "a"},
{"aa", "aa"}};
u.insert(std::begin(v2), std::end(v2));
EXPECT_NE(u, t);
}

@ -23,11 +23,11 @@ namespace absl {
namespace container_internal {
namespace {
using SetTypes =
::testing::Types<std::unordered_set<int, StatefulTestingHash,
StatefulTestingEqual, Alloc<int>>,
std::unordered_set<std::string, StatefulTestingHash,
StatefulTestingEqual, Alloc<std::string>>>;
using SetTypes = ::testing::Types<
std::unordered_set<int, StatefulTestingHash, StatefulTestingEqual,
Alloc<int>>,
std::unordered_set<std::string, StatefulTestingHash, StatefulTestingEqual,
Alloc<std::string>>>;
INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedSet, ConstructorTest, SetTypes);
INSTANTIATE_TYPED_TEST_SUITE_P(UnorderedSet, LookupTest, SetTypes);

@ -133,7 +133,8 @@ constexpr int kFailureSignals[] = {
};
std::string SignalParamToString(const ::testing::TestParamInfo<int>& info) {
std::string result = absl::debugging_internal::FailureSignalToString(info.param);
std::string result =
absl::debugging_internal::FailureSignalToString(info.param);
if (result.empty()) {
result = absl::StrCat(info.param);
}

@ -20,7 +20,6 @@
#include <cstddef>
#include <cstdint>
#include "absl/base/port.h" // Needed for string vs std::string
#ifdef ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE
#error ABSL_INTERNAL_HAVE_ELF_SYMBOLIZE cannot be directly set
@ -42,9 +41,9 @@ namespace debugging_internal {
// Returns true on success; otherwise returns false in case of errors.
//
// This is not async-signal-safe.
bool ForEachSection(
int fd, const std::function<bool(const std::string& name, const ElfW(Shdr) &)>&
callback);
bool ForEachSection(int fd,
const std::function<bool(const std::string& name,
const ElfW(Shdr) &)>& callback);
// Gets the section header for the given name, if it exists. Returns true on
// success. Otherwise, returns false.

@ -925,6 +925,14 @@ static const char *GetHex(const char *start, const char *end,
return p;
}
// Normally we are only interested in "r?x" maps.
// On the PowerPC, function pointers point to descriptors in the .opd
// section. The descriptors themselves are not executable code, so
// we need to relax the check below to "r??".
static bool ShouldUseMapping(const char *const flags) {
return flags[0] == 'r' && (kPlatformUsesOPDSections || flags[2] == 'x');
}
// Read /proc/self/maps and run "callback" for each mmapped file found. If
// "callback" returns false, stop scanning and return true. Else continue
// scanning /proc/self/maps. Return true if no parse error is found.
@ -994,12 +1002,8 @@ static ABSL_ATTRIBUTE_NOINLINE bool ReadAddrMap(
return false;
}
// Check flags. Normally we are only interested in "r-x" maps. On
// the PowerPC, function pointers point to descriptors in the .opd
// section. The descriptors themselves are not executable code. So
// we need to relax the check below to "r**".
if (memcmp(flags_start, "r-x", 3) != 0 && // Not a "r-x" map.
!(kPlatformUsesOPDSections && flags_start[0] == 'r')) {
// Check flags.
if (!ShouldUseMapping(flags_start)) {
continue; // We skip this map.
}
++cursor; // Skip ' '.

@ -243,7 +243,7 @@ using Hash = absl::hash_internal::Hash<T>;
// absl::HashState::combine(std::move(state), v1_, v2_);
// }
// int v1_;
// string v2_;
// std::string v2_;
// };
class HashState : public hash_internal::HashStateBase<HashState> {
public:

@ -275,7 +275,6 @@ struct WrapInTuple {
TEST(HashValueTest, Strings) {
EXPECT_TRUE((is_hashable<std::string>::value));
EXPECT_TRUE((is_hashable<std::string>::value));
const std::string small = "foo";
const std::string dup = "foofoo";
@ -705,7 +704,8 @@ TEST(HashTest, HashNonUniquelyRepresentedType) {
}
TEST(HashTest, StandardHashContainerUsage) {
std::unordered_map<int, std::string, Hash<int>> map = {{0, "foo"}, { 42, "bar" }};
std::unordered_map<int, std::string, Hash<int>> map = {{0, "foo"},
{42, "bar"}};
EXPECT_NE(map.find(0), map.end());
EXPECT_EQ(map.find(1), map.end());
@ -775,4 +775,24 @@ TEST(HashTest, TypeErased) {
SpyHash(std::make_pair(size_t{7}, 17)));
}
struct ValueWithBoolConversion {
operator bool() const { return false; }
int i;
};
} // namespace
namespace std {
template <>
struct hash<ValueWithBoolConversion> {
size_t operator()(ValueWithBoolConversion v) { return v.i; }
};
} // namespace std
namespace {
TEST(HashTest, DoesNotUseImplicitConversionsToBool) {
EXPECT_NE(absl::Hash<ValueWithBoolConversion>()(ValueWithBoolConversion{0}),
absl::Hash<ValueWithBoolConversion>()(ValueWithBoolConversion{1}));
}
} // namespace

@ -190,7 +190,9 @@ VerifyTypeImplementsAbslHashCorrectly(const Container& values, Eq equals) {
struct Info {
const V& value;
size_t index;
std::string ToString() const { return absl::visit(PrintVisitor{index}, value); }
std::string ToString() const {
return absl::visit(PrintVisitor{index}, value);
}
SpyHashState expand() const { return absl::visit(ExpandVisitor{}, value); }
};

@ -221,7 +221,9 @@ typename std::enable_if<std::is_enum<Enum>::value, H>::type AbslHashValue(
}
// AbslHashValue() for hashing floating-point values
template <typename H, typename Float>
typename std::enable_if<std::is_floating_point<Float>::value, H>::type
typename std::enable_if<std::is_same<Float, float>::value ||
std::is_same<Float, double>::value,
H>::type
AbslHashValue(H hash_state, Float value) {
return hash_internal::hash_bytes(std::move(hash_state),
value == 0 ? 0 : value);
@ -231,8 +233,9 @@ AbslHashValue(H hash_state, Float value) {
// For example, in x86 sizeof(long double)==16 but it only really uses 80-bits
// of it. This means we can't use hash_bytes on a long double and have to
// convert it to something else first.
template <typename H>
H AbslHashValue(H hash_state, long double value) {
template <typename H, typename LongDouble>
typename std::enable_if<std::is_same<LongDouble, long double>::value, H>::type
AbslHashValue(H hash_state, LongDouble value) {
const int category = std::fpclassify(value);
switch (category) {
case FP_INFINITE:

@ -39,8 +39,7 @@ namespace hash_internal {
template <typename T>
class SpyHashStateImpl : public HashStateBase<SpyHashStateImpl<T>> {
public:
SpyHashStateImpl()
: error_(std::make_shared<absl::optional<std::string>>()) {
SpyHashStateImpl() : error_(std::make_shared<absl::optional<std::string>>()) {
static_assert(std::is_void<T>::value, "");
}
@ -170,7 +169,6 @@ class SpyHashStateImpl : public HashStateBase<SpyHashStateImpl<T>> {
// AbslHashValue directly (because the hash state type does not match).
static bool direct_absl_hash_value_error_;
std::vector<std::string> hash_representation_;
// This is a shared_ptr because we want all instances of the particular
// SpyHashState run to share the field. This way we can set the error for

@ -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);

@ -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);
}

@ -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 {

@ -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_; }

@ -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);

@ -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);

@ -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);

@ -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 {

@ -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<>("%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<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<std::string, int>("%2$*1$s"), //
ValidFormat<std::string>("%1$p"),

@ -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
};

@ -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) {

@ -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);

@ -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 {

@ -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'};

@ -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;

@ -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());
}

@ -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());

@ -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);

@ -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", "!");

@ -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.

@ -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);
}

@ -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());
}

@ -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);

@ -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);
}
{

@ -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);
}

@ -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());

@ -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");
}

@ -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);
}

@ -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)));
// }

@ -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);
}
}

@ -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.";

@ -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.

@ -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()));

@ -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 "

@ -114,10 +114,9 @@ class PerThreadSemTest : public testing::Test {
min_cycles = std::min(min_cycles, cycles);
total_cycles += cycles;
}
std::string out =
StrCat(msg, "min cycle count=", min_cycles, " avg cycle count=",
absl::SixDigits(static_cast<double>(total_cycles) /
kNumIterations));
std::string out = StrCat(
msg, "min cycle count=", min_cycles, " avg cycle count=",
absl::SixDigits(static_cast<double>(total_cycles) / kNumIterations));
printf("%s\n", out.c_str());
partner_thread.join();

@ -110,6 +110,7 @@ cc_test(
":test_util",
":time",
"//absl/base",
"//absl/base:core_headers",
"//absl/hash",
"@com_github_google_benchmark//:benchmark_main",
],

@ -38,7 +38,8 @@ std::string FormatYearAnd(string_view fmt, CivilSecond cs) {
cs.hour(), cs.minute(), cs.second());
const TimeZone utc = UTCTimeZone();
// TODO(absl-team): Avoid conversion of fmt std::string.
return StrCat(cs.year(), FormatTime(std::string(fmt), FromCivil(ncs, utc), utc));
return StrCat(cs.year(),
FormatTime(std::string(fmt), FromCivil(ncs, utc), utc));
}
} // namespace
@ -52,15 +53,9 @@ std::string FormatCivilTime(CivilMinute c) {
std::string FormatCivilTime(CivilHour c) {
return FormatYearAnd("-%m-%dT%H", c);
}
std::string FormatCivilTime(CivilDay c) {
return FormatYearAnd("-%m-%d", c);
}
std::string FormatCivilTime(CivilMonth c) {
return FormatYearAnd("-%m", c);
}
std::string FormatCivilTime(CivilYear c) {
return FormatYearAnd("", c);
}
std::string FormatCivilTime(CivilDay c) { return FormatYearAnd("-%m-%d", c); }
std::string FormatCivilTime(CivilMonth c) { return FormatYearAnd("-%m", c); }
std::string FormatCivilTime(CivilYear c) { return FormatYearAnd("", c); }
namespace time_internal {

@ -451,7 +451,7 @@ inline int GetYearDay(CivilDay cd) {
// Example:
//
// absl::CivilDay d = absl::CivilDay(1969, 7, 20);
// string day_string = absl::FormatCivilTime(d); // "1969-07-20"
// std::string day_string = absl::FormatCivilTime(d); // "1969-07-20"
//
std::string FormatCivilTime(CivilSecond c);
std::string FormatCivilTime(CivilMinute c);

@ -751,7 +751,7 @@ void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) {
// From Go's doc at http://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
// 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
// is non-zero. The zero duration formats as 0, with no unit.
@ -856,7 +856,7 @@ 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
// [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".

@ -17,6 +17,7 @@
#include <ctime>
#include <string>
#include "absl/base/attributes.h"
#include "absl/time/time.h"
#include "benchmark/benchmark.h"

@ -1771,7 +1771,7 @@ TEST(Duration, ParseDuration) {
TEST(Duration, FormatParseRoundTrip) {
#define TEST_PARSE_ROUNDTRIP(d) \
do { \
std::string s = absl::FormatDuration(d); \
std::string s = absl::FormatDuration(d); \
absl::Duration dur; \
EXPECT_TRUE(absl::ParseDuration(s, &dur)); \
EXPECT_EQ(d, dur); \

@ -67,7 +67,8 @@ absl::Time Join(const cctz_parts& parts) {
} // namespace
std::string FormatTime(const std::string& format, absl::Time t, absl::TimeZone tz) {
std::string FormatTime(const std::string& format, absl::Time t,
absl::TimeZone tz) {
if (t == absl::InfiniteFuture()) return kInfiniteFutureStr;
if (t == absl::InfinitePast()) return kInfinitePastStr;
const auto parts = Split(t);
@ -83,15 +84,15 @@ std::string FormatTime(absl::Time t) {
return absl::FormatTime(RFC3339_full, t, absl::LocalTimeZone());
}
bool ParseTime(const std::string& format, const std::string& input, absl::Time* time,
std::string* err) {
bool ParseTime(const std::string& format, const std::string& input,
absl::Time* time, std::string* err) {
return absl::ParseTime(format, input, absl::UTCTimeZone(), time, err);
}
// 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) {
bool ParseTime(const std::string& format, const std::string& input,
absl::TimeZone tz, absl::Time* time, std::string* err) {
const char* data = input.c_str();
while (std::isspace(*data)) ++data;

@ -27,8 +27,8 @@ namespace {
// A helper that tests the given format specifier by itself, and with leading
// and trailing characters. For example: TestFormatSpecifier(t, "%a", "Thu").
void TestFormatSpecifier(absl::Time t, absl::TimeZone tz, const std::string& fmt,
const std::string& ans) {
void TestFormatSpecifier(absl::Time t, absl::TimeZone tz,
const std::string& fmt, const std::string& ans) {
EXPECT_EQ(ans, absl::FormatTime(fmt, t, tz));
EXPECT_EQ("xxx " + ans, absl::FormatTime("xxx " + fmt, t, tz));
EXPECT_EQ(ans + " yyy", absl::FormatTime(fmt + " yyy", t, tz));
@ -375,7 +375,8 @@ TEST(FormatParse, RoundTrip) {
// RFC3339, which renders subseconds.
{
absl::Time out;
const std::string s = absl::FormatTime(absl::RFC3339_full, in + subseconds, lax);
const std::string s =
absl::FormatTime(absl::RFC3339_full, in + subseconds, lax);
EXPECT_TRUE(absl::ParseTime(absl::RFC3339_full, s, &out, &err))
<< s << ": " << err;
EXPECT_EQ(in + subseconds, out); // RFC3339_full includes %Ez

@ -77,7 +77,6 @@
#include <type_traits>
#include <utility>
#include "absl/base/port.h" // Needed for string vs std::string
#include "absl/strings/string_view.h"
#include "absl/time/civil_time.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
@ -1222,7 +1221,7 @@ extern const char RFC1123_no_wday[]; // %d %b %E4Y %H:%M:%S %z
//
// absl::CivilSecond cs(2013, 1, 2, 3, 4, 5);
// absl::Time t = absl::FromCivil(cs, lax);
// string f = absl::FormatTime("%H:%M:%S", t, lax); // "03:04:05"
// std::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

@ -1476,8 +1476,8 @@ TEST(optionalTest, MoveAssignRegression) {
TEST(optionalTest, ValueType) {
EXPECT_TRUE((std::is_same<absl::optional<int>::value_type, int>::value));
EXPECT_TRUE(
(std::is_same<absl::optional<std::string>::value_type, std::string>::value));
EXPECT_TRUE((std::is_same<absl::optional<std::string>::value_type,
std::string>::value));
EXPECT_FALSE(
(std::is_same<absl::optional<int>::value_type, absl::nullopt_t>::value));
}

@ -87,7 +87,7 @@ constexpr auto GetDataImpl(C& c, char) noexcept // NOLINT(runtime/references)
return c.data();
}
// Before C++17, string::data returns a const char* in all cases.
// Before C++17, std::string::data returns a const char* in all cases.
inline char* GetDataImpl(std::string& s, // NOLINT(runtime/references)
int) noexcept {
return &s[0];

@ -139,8 +139,10 @@ TEST(CharSpan, StringCtor) {
EXPECT_THAT(s_const_abc, SpanIs(abc));
EXPECT_FALSE((std::is_constructible<absl::Span<int>, std::string>::value));
EXPECT_FALSE((std::is_constructible<absl::Span<const int>, std::string>::value));
EXPECT_TRUE((std::is_convertible<std::string, absl::Span<const char>>::value));
EXPECT_FALSE(
(std::is_constructible<absl::Span<const int>, std::string>::value));
EXPECT_TRUE(
(std::is_convertible<std::string, absl::Span<const char>>::value));
}
TEST(IntSpan, FromConstPointer) {

@ -484,7 +484,8 @@ TEST(VariantTest, InPlaceType) {
}
TEST(VariantTest, InPlaceTypeInitializerList) {
using Var = variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
using Var =
variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
Var v1(in_place_type_t<MoveOnlyWithListConstructor>(), {1, 2, 3, 4, 5}, 6);
ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1));
@ -519,7 +520,8 @@ TEST(VariantTest, InPlaceIndex) {
}
TEST(VariantTest, InPlaceIndexInitializerList) {
using Var = variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
using Var =
variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
Var v1(in_place_index_t<3>(), {1, 2, 3, 4, 5}, 6);
ASSERT_TRUE(absl::holds_alternative<MoveOnlyWithListConstructor>(v1));
@ -831,7 +833,8 @@ TEST(VariantTest, TestEmplaceBasic) {
}
TEST(VariantTest, TestEmplaceInitializerList) {
using Var = variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
using Var =
variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
Var v1(absl::in_place_index_t<0>{}, 555);
MoveOnlyWithListConstructor& emplace_result =
@ -868,7 +871,8 @@ TEST(VariantTest, TestEmplaceIndex) {
}
TEST(VariantTest, TestEmplaceIndexInitializerList) {
using Var = variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
using Var =
variant<int, std::string, NonCopyable, MoveOnlyWithListConstructor>;
Var v1(absl::in_place_index_t<0>{}, 555);
MoveOnlyWithListConstructor& emplace_result =
@ -1306,7 +1310,8 @@ TEST(VariantTest, BadGetType) {
absl::get<std::string>(std::move(v)));
const Var& const_v = v;
ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(absl::get<std::string>(const_v));
ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(
absl::get<std::string>(const_v));
ABSL_VARIANT_TEST_EXPECT_BAD_VARIANT_ACCESS(
absl::get<std::string>(std::move(const_v))); // NOLINT
}
@ -1363,7 +1368,8 @@ TEST(VariantTest, GetIfIndex) {
EXPECT_EQ(*elem, 0);
{
auto* bad_elem = absl::get_if<1>(&const_v);
EXPECT_TRUE((std::is_same<decltype(bad_elem), const std::string*>::value));
EXPECT_TRUE(
(std::is_same<decltype(bad_elem), const std::string*>::value));
EXPECT_EQ(bad_elem, nullptr);
}
{
@ -1472,7 +1478,8 @@ TEST(VariantTest, GetIfIndex) {
}
{
auto* bad_elem = absl::get_if<1>(&const_v);
EXPECT_TRUE((std::is_same<decltype(bad_elem), const std::string*>::value));
EXPECT_TRUE(
(std::is_same<decltype(bad_elem), const std::string*>::value));
EXPECT_EQ(bad_elem, nullptr);
}
{
@ -1525,7 +1532,8 @@ TEST(VariantTest, GetIfIndex) {
}
{
auto* bad_elem = absl::get_if<1>(&const_v);
EXPECT_TRUE((std::is_same<decltype(bad_elem), const std::string*>::value));
EXPECT_TRUE(
(std::is_same<decltype(bad_elem), const std::string*>::value));
EXPECT_EQ(bad_elem, nullptr);
}
{
@ -1728,9 +1736,13 @@ TEST(VariantTest, VisitRValue) {
bool operator()(std::string&&) const { return true; } // NOLINT
int operator()(const std::string&, const std::string&) const { return 0; }
int operator()(const std::string&, std::string&&) const { return 1; } // NOLINT
int operator()(std::string&&, const std::string&) const { return 2; } // NOLINT
int operator()(std::string&&, std::string&&) const { return 3; } // NOLINT
int operator()(const std::string&, std::string&&) const {
return 1;
} // NOLINT
int operator()(std::string&&, const std::string&) const {
return 2;
} // NOLINT
int operator()(std::string&&, std::string&&) const { return 3; } // NOLINT
};
EXPECT_FALSE(absl::visit(Visitor{}, v));
EXPECT_TRUE(absl::visit(Visitor{}, absl::move(v)));
@ -1806,9 +1818,9 @@ TEST(VariantTest, VisitVariadic) {
EXPECT_THAT(absl::visit(Visitor(), A(std::string("BBBBB")),
B(std::unique_ptr<int>(new int(7)))),
::testing::Pair(5, 7));
EXPECT_THAT(
absl::visit(Visitor(), A(std::string("BBBBB")), B(absl::string_view("ABC"))),
::testing::Pair(5, 3));
EXPECT_THAT(absl::visit(Visitor(), A(std::string("BBBBB")),
B(absl::string_view("ABC"))),
::testing::Pair(5, 3));
}
TEST(VariantTest, VisitNoArgs) {
@ -2163,7 +2175,8 @@ TEST(VariantTest, TestImplicitConversion) {
// We still need the explicit cast for std::string, because C++ won't apply
// two user-defined implicit conversions in a row.
EXPECT_TRUE(absl::holds_alternative<std::string>(PassThrough(std::string("foo"))));
EXPECT_TRUE(
absl::holds_alternative<std::string>(PassThrough(std::string("foo"))));
}
struct Convertible2;
@ -2187,7 +2200,8 @@ struct Convertible2 {
TEST(VariantTest, TestRvalueConversion) {
variant<double, std::string> var(
ConvertVariantTo<variant<double, std::string>>(variant<std::string, int>(0)));
ConvertVariantTo<variant<double, std::string>>(
variant<std::string, int>(0)));
ASSERT_TRUE(absl::holds_alternative<double>(var));
EXPECT_EQ(0.0, absl::get<double>(var));
@ -2279,7 +2293,8 @@ TEST(VariantTest, TestLvalueConversion) {
TEST(VariantTest, TestMoveConversion) {
using Variant =
variant<std::unique_ptr<const int>, std::unique_ptr<const std::string>>;
using OtherVariant = variant<std::unique_ptr<int>, std::unique_ptr<std::string>>;
using OtherVariant =
variant<std::unique_ptr<int>, std::unique_ptr<std::string>>;
Variant var(
ConvertVariantTo<Variant>(OtherVariant{absl::make_unique<int>(0)}));
@ -2287,8 +2302,8 @@ TEST(VariantTest, TestMoveConversion) {
ASSERT_NE(absl::get<std::unique_ptr<const int>>(var), nullptr);
EXPECT_EQ(0, *absl::get<std::unique_ptr<const int>>(var));
var =
ConvertVariantTo<Variant>(OtherVariant(absl::make_unique<std::string>("foo")));
var = ConvertVariantTo<Variant>(
OtherVariant(absl::make_unique<std::string>("foo")));
ASSERT_TRUE(absl::holds_alternative<std::unique_ptr<const std::string>>(var));
EXPECT_EQ("foo", *absl::get<std::unique_ptr<const std::string>>(var));
}
@ -2299,7 +2314,8 @@ TEST(VariantTest, DoesNotMoveFromLvalues) {
// whether moving or copying has occurred.
using Variant =
variant<std::shared_ptr<const int>, std::shared_ptr<const std::string>>;
using OtherVariant = variant<std::shared_ptr<int>, std::shared_ptr<std::string>>;
using OtherVariant =
variant<std::shared_ptr<int>, std::shared_ptr<std::string>>;
Variant v1(std::make_shared<const int>(0));
@ -2328,7 +2344,8 @@ TEST(VariantTest, DoesNotMoveFromLvalues) {
TEST(VariantTest, TestRvalueConversionViaConvertVariantTo) {
variant<double, std::string> var(
ConvertVariantTo<variant<double, std::string>>(variant<std::string, int>(3)));
ConvertVariantTo<variant<double, std::string>>(
variant<std::string, int>(3)));
EXPECT_THAT(absl::get_if<double>(&var), Pointee(3.0));
var = ConvertVariantTo<variant<double, std::string>>(
@ -2370,7 +2387,8 @@ TEST(VariantTest, TestLvalueConversionViaConvertVariantTo) {
variant<const char*, float> source2 = "foo";
destination = ConvertVariantTo<variant<double, std::string>>(source2);
EXPECT_THAT(absl::get_if<std::string>(&destination), Pointee(std::string("foo")));
EXPECT_THAT(absl::get_if<std::string>(&destination),
Pointee(std::string("foo")));
variant<int, float> source3(42);
variant<double> singleton(ConvertVariantTo<variant<double>>(source3));
@ -2407,15 +2425,16 @@ TEST(VariantTest, TestLvalueConversionViaConvertVariantTo) {
TEST(VariantTest, TestMoveConversionViaConvertVariantTo) {
using Variant =
variant<std::unique_ptr<const int>, std::unique_ptr<const std::string>>;
using OtherVariant = variant<std::unique_ptr<int>, std::unique_ptr<std::string>>;
using OtherVariant =
variant<std::unique_ptr<int>, std::unique_ptr<std::string>>;
Variant var(
ConvertVariantTo<Variant>(OtherVariant{absl::make_unique<int>(3)}));
EXPECT_THAT(absl::get_if<std::unique_ptr<const int>>(&var),
Pointee(Pointee(3)));
var =
ConvertVariantTo<Variant>(OtherVariant(absl::make_unique<std::string>("foo")));
var = ConvertVariantTo<Variant>(
OtherVariant(absl::make_unique<std::string>("foo")));
EXPECT_THAT(absl::get_if<std::unique_ptr<const std::string>>(&var),
Pointee(Pointee(std::string("foo"))));
}

@ -238,14 +238,14 @@ auto apply_helper(Functor&& functor, Tuple&& t, index_sequence<Indexes...>)
// public:
// void Bar(int);
// };
// void user_function1(int, string);
// void user_function1(int, std::string);
// void user_function2(std::unique_ptr<Foo>);
// auto user_lambda = [](int, int) {};
//
// int main()
// {
// std::tuple<int, string> tuple1(42, "bar");
// // Invokes the first user function on int, string.
// std::tuple<int, std::string> tuple1(42, "bar");
// // Invokes the first user function on int, std::string.
// absl::apply(&user_function1, tuple1);
//
// std::tuple<std::unique_ptr<Foo>> tuple2(absl::make_unique<Foo>());

@ -135,7 +135,7 @@ struct PoorStrCat {
template <typename Tup, size_t... Is>
std::vector<std::string> TupStringVecImpl(const Tup& tup,
absl::index_sequence<Is...>) {
absl::index_sequence<Is...>) {
return {Fmt(std::get<Is>(tup))...};
}

Loading…
Cancel
Save