Browse Source

More usage of abseil packages. Especially for string util usages. (#2734)

- Faced link errors stemmed from mismatch of api definitions of absl::node_hash_set. So explicitly mentioned this lib as dependency during linking. This is common case/solution for absl hash set lib's link errors as per community.
- Decided to continued to have wrapper (stringutil), so that in future it's easy if we decided to change implementation; client code is safe. Changed most of the implementations & data structures in stringutil, to use abseil stuffs more.
- Though absl::string_view is suitable for most cases where we want immutable/read-only string structures, limiting to stringutil apis, not changing public API signatures (even though no compliance issue); reason: reduce dependency on abseil libs.
- Abseil specific changes done:
    - std::set => absl::node_hash_set
    - std::map => absl::node_hash_map
    - Using absl alternatives for “SplitStringUsing” API and “StringHolder” class impl.
    - Replaced manual impl of prefix and suffix checks with absl::StartsWith() and absl::EndsWith.
    - Similarly used absl::StrReplaceAll, absl::StrCat, absl::StrAppend where possible; and for type conversion apis.
- Note: Tried applying parameter packs to replace manually written duplicate ```StrCat``` apis (for accommodating more number of parameters of same type), but it did not go well when different type arguments passed. Eg char, int types to be converted to StringHolder; faced constructor implicit conversion issues.
pull/2739/head
penmetsaa 4 years ago
committed by GitHub
parent
commit
5719f3a724
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 88 additions and 372 deletions
  1. +2
    -2
      cpp/CMakeLists.txt
  2. +1
    -3
      cpp/src/phonenumbers/asyoutypeformatter.cc
  3. +2
    -2
      cpp/src/phonenumbers/phonenumbermatcher.cc
  4. +13
    -15
      cpp/src/phonenumbers/phonenumberutil.cc
  5. +6
    -3
      cpp/src/phonenumbers/phonenumberutil.h
  6. +2
    -3
      cpp/src/phonenumbers/regexp_adapter_re2.cc
  7. +42
    -307
      cpp/src/phonenumbers/stringutil.cc
  8. +10
    -18
      cpp/src/phonenumbers/stringutil.h
  9. +8
    -17
      cpp/test/phonenumbers/stringutil_test.cc
  10. +2
    -2
      tools/cpp/CMakeLists.txt

+ 2
- 2
cpp/CMakeLists.txt View File

@ -570,7 +570,7 @@ if (NOT WIN32)
list (APPEND TEST_LIBS pthread) list (APPEND TEST_LIBS pthread)
endif () endif ()
target_link_libraries (libphonenumber_test ${TEST_LIBS})
target_link_libraries (libphonenumber_test ${TEST_LIBS} absl::node_hash_set)
# Unfortunately add_custom_target() can't accept a single command provided as a # Unfortunately add_custom_target() can't accept a single command provided as a
# list of commands. # list of commands.
@ -677,7 +677,7 @@ if (${BUILD_GEOCODER} STREQUAL "ON")
geocoding_test_program geocoding_test_program
"test/phonenumbers/geocoding/geocoding_test_program.cc" "test/phonenumbers/geocoding/geocoding_test_program.cc"
) )
target_link_libraries (geocoding_test_program geocoding phonenumber)
target_link_libraries (geocoding_test_program geocoding phonenumber absl::node_hash_set)
endif () endif ()
# Build an RPM # Build an RPM


+ 1
- 3
cpp/src/phonenumbers/asyoutypeformatter.cc View File

@ -29,8 +29,6 @@
#include "phonenumbers/stringutil.h" #include "phonenumbers/stringutil.h"
#include "phonenumbers/unicodestring.h" #include "phonenumbers/unicodestring.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
namespace i18n { namespace i18n {
namespace phonenumbers { namespace phonenumbers {
@ -276,7 +274,7 @@ void AsYouTypeFormatter::GetFormattingTemplate(
regexp_cache_.GetRegExp(number_pattern).GlobalReplace( regexp_cache_.GetRegExp(number_pattern).GlobalReplace(
&a_phone_number, number_format); &a_phone_number, number_format);
// Replaces each digit with character kDigitPlaceholder. // Replaces each digit with character kDigitPlaceholder.
absl::StrReplaceAll({{"9", kDigitPlaceholder}}, &a_phone_number);
GlobalReplaceSubstring("9", kDigitPlaceholder, &a_phone_number);
formatting_template->setTo(a_phone_number.c_str(), a_phone_number.size()); formatting_template->setTo(a_phone_number.c_str(), a_phone_number.size());
} }


+ 2
- 2
cpp/src/phonenumbers/phonenumbermatcher.cc View File

@ -756,7 +756,7 @@ void PhoneNumberMatcher::GetNationalNumberGroups(
size_t start_index = rfc3966_format.find('-') + 1; size_t start_index = rfc3966_format.find('-') + 1;
SplitStringUsing(rfc3966_format.substr(start_index, SplitStringUsing(rfc3966_format.substr(start_index,
end_index - start_index), end_index - start_index),
"-", digit_blocks);
'-', digit_blocks);
} }
void PhoneNumberMatcher::GetNationalNumberGroupsForPattern( void PhoneNumberMatcher::GetNationalNumberGroupsForPattern(
@ -772,7 +772,7 @@ void PhoneNumberMatcher::GetNationalNumberGroupsForPattern(
*formatting_pattern, *formatting_pattern,
PhoneNumberUtil::RFC3966, PhoneNumberUtil::RFC3966,
&rfc3966_format); &rfc3966_format);
SplitStringUsing(rfc3966_format, "-", digit_blocks);
SplitStringUsing(rfc3966_format, '-', digit_blocks);
} }
bool PhoneNumberMatcher::IsNationalPrefixPresentIfRequired( bool PhoneNumberMatcher::IsNationalPrefixPresentIfRequired(


+ 13
- 15
cpp/src/phonenumbers/phonenumberutil.cc View File

@ -47,8 +47,6 @@
#include "phonenumbers/utf/unicodetext.h" #include "phonenumbers/utf/unicodetext.h"
#include "phonenumbers/utf/utf.h" #include "phonenumbers/utf/utf.h"
#include "absl/strings/str_replace.h"
namespace i18n { namespace i18n {
namespace phonenumbers { namespace phonenumbers {
@ -830,10 +828,10 @@ PhoneNumberUtil::PhoneNumberUtil()
reg_exps_(new PhoneNumberRegExpsAndMappings), reg_exps_(new PhoneNumberRegExpsAndMappings),
country_calling_code_to_region_code_map_( country_calling_code_to_region_code_map_(
new std::vector<IntRegionsPair>()), new std::vector<IntRegionsPair>()),
nanpa_regions_(new std::set<string>()),
region_to_metadata_map_(new std::map<string, PhoneMetadata>()),
nanpa_regions_(new absl::node_hash_set<string>()),
region_to_metadata_map_(new absl::node_hash_map<string, PhoneMetadata>()),
country_code_to_non_geographical_metadata_map_( country_code_to_non_geographical_metadata_map_(
new std::map<int, PhoneMetadata>) {
new absl::node_hash_map<int, PhoneMetadata>) {
Logger::set_logger_impl(logger_.get()); Logger::set_logger_impl(logger_.get());
// TODO: Update the java version to put the contents of the init // TODO: Update the java version to put the contents of the init
// method inside the constructor as well to keep both in sync. // method inside the constructor as well to keep both in sync.
@ -896,9 +894,10 @@ PhoneNumberUtil::~PhoneNumberUtil() {
country_calling_code_to_region_code_map_->end()); country_calling_code_to_region_code_map_->end());
} }
void PhoneNumberUtil::GetSupportedRegions(std::set<string>* regions) const {
void PhoneNumberUtil::GetSupportedRegions(std::set<string>* regions)
const {
DCHECK(regions); DCHECK(regions);
for (std::map<string, PhoneMetadata>::const_iterator it =
for (absl::node_hash_map<string, PhoneMetadata>::const_iterator it =
region_to_metadata_map_->begin(); it != region_to_metadata_map_->end(); region_to_metadata_map_->begin(); it != region_to_metadata_map_->end();
++it) { ++it) {
regions->insert(it->first); regions->insert(it->first);
@ -908,7 +907,7 @@ void PhoneNumberUtil::GetSupportedRegions(std::set<string>* regions) const {
void PhoneNumberUtil::GetSupportedGlobalNetworkCallingCodes( void PhoneNumberUtil::GetSupportedGlobalNetworkCallingCodes(
std::set<int>* calling_codes) const { std::set<int>* calling_codes) const {
DCHECK(calling_codes); DCHECK(calling_codes);
for (std::map<int, PhoneMetadata>::const_iterator it =
for (absl::node_hash_map<int, PhoneMetadata>::const_iterator it =
country_code_to_non_geographical_metadata_map_->begin(); country_code_to_non_geographical_metadata_map_->begin();
it != country_code_to_non_geographical_metadata_map_->end(); ++it) { it != country_code_to_non_geographical_metadata_map_->end(); ++it) {
calling_codes->insert(it->first); calling_codes->insert(it->first);
@ -1065,7 +1064,7 @@ bool PhoneNumberUtil::HasValidCountryCallingCode(
// if the region code is invalid or unknown. // if the region code is invalid or unknown.
const PhoneMetadata* PhoneNumberUtil::GetMetadataForRegion( const PhoneMetadata* PhoneNumberUtil::GetMetadataForRegion(
const string& region_code) const { const string& region_code) const {
std::map<string, PhoneMetadata>::const_iterator it =
absl::node_hash_map<string, PhoneMetadata>::const_iterator it =
region_to_metadata_map_->find(region_code); region_to_metadata_map_->find(region_code);
if (it != region_to_metadata_map_->end()) { if (it != region_to_metadata_map_->end()) {
return &it->second; return &it->second;
@ -1075,7 +1074,7 @@ const PhoneMetadata* PhoneNumberUtil::GetMetadataForRegion(
const PhoneMetadata* PhoneNumberUtil::GetMetadataForNonGeographicalRegion( const PhoneMetadata* PhoneNumberUtil::GetMetadataForNonGeographicalRegion(
int country_calling_code) const { int country_calling_code) const {
std::map<int, PhoneMetadata>::const_iterator it =
absl::node_hash_map<int, PhoneMetadata>::const_iterator it =
country_code_to_non_geographical_metadata_map_->find( country_code_to_non_geographical_metadata_map_->find(
country_calling_code); country_calling_code);
if (it != country_code_to_non_geographical_metadata_map_->end()) { if (it != country_code_to_non_geographical_metadata_map_->end()) {
@ -1175,9 +1174,9 @@ void PhoneNumberUtil::FormatByPattern(
const string& national_prefix = metadata->national_prefix(); const string& national_prefix = metadata->national_prefix();
if (!national_prefix.empty()) { if (!national_prefix.empty()) {
// Replace $NP with national prefix and $FG with the first group ($1). // Replace $NP with national prefix and $FG with the first group ($1).
absl::StrReplaceAll({{"$NP", national_prefix}},
GlobalReplaceSubstring("$NP", national_prefix,
&national_prefix_formatting_rule); &national_prefix_formatting_rule);
absl::StrReplaceAll({{"$FG", "$1"}}, &national_prefix_formatting_rule);
GlobalReplaceSubstring("$FG", "$1", &national_prefix_formatting_rule);
num_format_copy.set_national_prefix_formatting_rule( num_format_copy.set_national_prefix_formatting_rule(
national_prefix_formatting_rule); national_prefix_formatting_rule);
} else { } else {
@ -2026,9 +2025,8 @@ bool PhoneNumberUtil::GetExampleNumberForType(
DCHECK(number); DCHECK(number);
std::set<string> regions; std::set<string> regions;
GetSupportedRegions(&regions); GetSupportedRegions(&regions);
for (std::set<string>::const_iterator it = regions.begin();
it != regions.end(); ++it) {
if (GetExampleNumberForType(*it, type, number)) {
for (const string& region_code : regions) {
if (GetExampleNumberForType(region_code, type, number)) {
return true; return true;
} }
} }


+ 6
- 3
cpp/src/phonenumbers/phonenumberutil.h View File

@ -30,6 +30,9 @@
#include "phonenumbers/base/memory/singleton.h" #include "phonenumbers/base/memory/singleton.h"
#include "phonenumbers/phonenumber.pb.h" #include "phonenumbers/phonenumber.pb.h"
#include "absl/container/node_hash_set.h"
#include "absl/container/node_hash_map.h"
class TelephoneNumber; class TelephoneNumber;
namespace i18n { namespace i18n {
@ -805,17 +808,17 @@ class PhoneNumberUtil : public Singleton<PhoneNumberUtil> {
country_calling_code_to_region_code_map_; country_calling_code_to_region_code_map_;
// The set of regions that share country calling code 1. // The set of regions that share country calling code 1.
scoped_ptr<std::set<string> > nanpa_regions_;
scoped_ptr<absl::node_hash_set<string> > nanpa_regions_;
static const int kNanpaCountryCode = 1; static const int kNanpaCountryCode = 1;
// A mapping from a region code to a PhoneMetadata for that region. // A mapping from a region code to a PhoneMetadata for that region.
scoped_ptr<std::map<string, PhoneMetadata> > region_to_metadata_map_;
scoped_ptr<absl::node_hash_map<string, PhoneMetadata> > region_to_metadata_map_;
// A mapping from a country calling code for a non-geographical entity to the // A mapping from a country calling code for a non-geographical entity to the
// PhoneMetadata for that country calling code. Examples of the country // PhoneMetadata for that country calling code. Examples of the country
// calling codes include 800 (International Toll Free Service) and 808 // calling codes include 800 (International Toll Free Service) and 808
// (International Shared Cost Service). // (International Shared Cost Service).
scoped_ptr<std::map<int, PhoneMetadata> >
scoped_ptr<absl::node_hash_map<int, PhoneMetadata> >
country_code_to_non_geographical_metadata_map_; country_code_to_non_geographical_metadata_map_;
PhoneNumberUtil(); PhoneNumberUtil();


+ 2
- 3
cpp/src/phonenumbers/regexp_adapter_re2.cc View File

@ -27,7 +27,6 @@
#include "phonenumbers/base/logging.h" #include "phonenumbers/base/logging.h"
#include "phonenumbers/stringutil.h" #include "phonenumbers/stringutil.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
namespace i18n { namespace i18n {
namespace phonenumbers { namespace phonenumbers {
@ -78,14 +77,14 @@ bool DispatchRE2Call(Function regex_function,
// when they escape dollar-signs. // when they escape dollar-signs.
string TransformRegularExpressionToRE2Syntax(const string& regex) { string TransformRegularExpressionToRE2Syntax(const string& regex) {
string re2_regex(regex); string re2_regex(regex);
if (absl::StrReplaceAll({{"$", "\\"}}, &re2_regex) == 0) {
if (GlobalReplaceSubstring("$", "\\", &re2_regex) == 0) {
return regex; return regex;
} }
// If we replaced a dollar sign with a backslash and there are now two // If we replaced a dollar sign with a backslash and there are now two
// backslashes in the string, we assume that the dollar-sign was previously // backslashes in the string, we assume that the dollar-sign was previously
// escaped and that we need to retain it. To do this, we replace pairs of // escaped and that we need to retain it. To do this, we replace pairs of
// backslashes with a dollar sign. // backslashes with a dollar sign.
absl::StrReplaceAll({{"\\\\", "$"}}, &re2_regex);
GlobalReplaceSubstring("\\\\", "$", &re2_regex);
return re2_regex; return re2_regex;
} }


+ 42
- 307
cpp/src/phonenumbers/stringutil.cc View File

@ -21,8 +21,9 @@
#include "phonenumbers/stringutil.h" #include "phonenumbers/stringutil.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/substitute.h"
#include "absl/strings/match.h"
namespace i18n { namespace i18n {
namespace phonenumbers { namespace phonenumbers {
@ -49,8 +50,7 @@ string SimpleItoa(int64 n) {
} }
bool HasPrefixString(const string& s, const string& prefix) { bool HasPrefixString(const string& s, const string& prefix) {
return s.size() >= prefix.size() &&
equal(s.begin(), s.begin() + prefix.size(), prefix.begin());
return absl::StartsWith(s, prefix);
} }
size_t FindNth(const string& s, char c, int n) { size_t FindNth(const string& s, char c, int n) {
@ -65,33 +65,12 @@ size_t FindNth(const string& s, char c, int n) {
return pos; return pos;
} }
void SplitStringUsing(const string& s, const string& delimiter,
void SplitStringUsing(const string& s, char delimiter,
vector<string>* result) { vector<string>* result) {
assert(result); assert(result);
size_t start_pos = 0;
size_t find_pos = string::npos;
if (delimiter.empty()) {
return;
}
while ((find_pos = s.find(delimiter, start_pos)) != string::npos) {
const string substring = s.substr(start_pos, find_pos - start_pos);
if (!substring.empty()) {
result->push_back(substring);
}
start_pos = find_pos + delimiter.length();
}
if (start_pos != s.length()) {
result->push_back(s.substr(start_pos));
}
}
void StripString(string* s, const char* remove, char replacewith) {
const char* str_start = s->c_str();
const char* str = str_start;
for (str = strpbrk(str, remove);
str != NULL;
str = strpbrk(str + 1, remove)) {
(*s)[str - str_start] = replacewith;
for (absl::string_view split_piece : absl::StrSplit(
s, absl::ByChar(delimiter), absl::SkipEmpty())) {
result->push_back(std::string(split_piece));
} }
} }
@ -104,17 +83,12 @@ bool TryStripPrefixString(const string& in, const string& prefix, string* out) {
} }
bool HasSuffixString(const string& s, const string& suffix) { bool HasSuffixString(const string& s, const string& suffix) {
if (s.length() < suffix.length()) {
return false;
}
return s.compare(s.length() - suffix.length(), suffix.length(), suffix) == 0;
return absl::EndsWith(s, suffix);
} }
template <typename T> template <typename T>
void GenericAtoi(const string& s, T* out) { void GenericAtoi(const string& s, T* out) {
stringstream stream;
stream << s;
stream >> *out;
absl::SimpleAtoi(s, out);
} }
void safe_strto32(const string& s, int32 *n) { void safe_strto32(const string& s, int32 *n) {
@ -143,47 +117,20 @@ void strrmm(string* s, const string& chars) {
int GlobalReplaceSubstring(const string& substring, int GlobalReplaceSubstring(const string& substring,
const string& replacement, const string& replacement,
string* s) { string* s) {
assert(s != NULL);
if (s->empty() || substring.empty())
return 0;
string tmp;
int num_replacements = 0;
int pos = 0;
for (size_t match_pos = s->find(substring.data(), pos, substring.length());
match_pos != string::npos;
pos = static_cast<int>(match_pos + substring.length()),
match_pos = s->find(substring.data(), pos, substring.length())) {
++num_replacements;
// Append the original content before the match.
tmp.append(*s, pos, match_pos - pos);
// Append the replacement for the match.
tmp.append(replacement.begin(), replacement.end());
}
// Append the content after the last match.
tmp.append(*s, pos, s->length() - pos);
s->swap(tmp);
return num_replacements;
return absl::StrReplaceAll({{substring, replacement}}, s);;
} }
// StringHolder class // StringHolder class
StringHolder::StringHolder(const string& s) StringHolder::StringHolder(const string& s)
: string_(&s),
cstring_(NULL),
len_(s.size())
: absl::AlphaNum(s)
{} {}
StringHolder::StringHolder(const char* s)
: string_(NULL),
cstring_(s),
len_(std::strlen(s))
StringHolder::StringHolder(const char* cp)
: absl::AlphaNum(cp)
{} {}
StringHolder::StringHolder(uint64 n) StringHolder::StringHolder(uint64 n)
: converted_string_(SimpleItoa(n)),
string_(&converted_string_),
cstring_(NULL),
len_(converted_string_.length())
: absl::AlphaNum(n)
{} {}
StringHolder::~StringHolder() {} StringHolder::~StringHolder() {}
@ -192,9 +139,9 @@ StringHolder::~StringHolder() {}
// Implements s += sh; (s: string, sh: StringHolder) // Implements s += sh; (s: string, sh: StringHolder)
string& operator+=(string& lhs, const StringHolder& rhs) { string& operator+=(string& lhs, const StringHolder& rhs) {
const string* const s = rhs.GetString();
if (s) {
lhs += *s;
absl::string_view s = rhs.GetString();;
if (s.size() != 0) {
lhs += s.data();
} else { } else {
const char* const cs = rhs.GetCString(); const char* const cs = rhs.GetCString();
if (cs) if (cs)
@ -204,87 +151,36 @@ string& operator+=(string& lhs, const StringHolder& rhs) {
} }
string StrCat(const StringHolder& s1, const StringHolder& s2) { string StrCat(const StringHolder& s1, const StringHolder& s2) {
string result;
result.reserve(s1.Length() + s2.Length() + 1);
result += s1;
result += s2;
return result;
return absl::StrCat(s1, s2);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3) { const StringHolder& s3) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + 1);
result += s1;
result += s2;
result += s3;
return result;
return absl::StrCat(s1, s2, s3);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4) { const StringHolder& s3, const StringHolder& s4) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() + 1);
result += s1;
result += s2;
result += s3;
result += s4;
return result;
return absl::StrCat(s1, s2, s3, s4);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4, const StringHolder& s3, const StringHolder& s4,
const StringHolder& s5) { const StringHolder& s5) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + 1);
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
return result;
return absl::StrCat(s1, s2, s3, s4, s5);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4, const StringHolder& s3, const StringHolder& s4,
const StringHolder& s5, const StringHolder& s6) { const StringHolder& s5, const StringHolder& s6) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + 1);
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
return result;
return absl::StrCat(s1, s2, s3, s4, s5, s6);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4, const StringHolder& s3, const StringHolder& s4,
const StringHolder& s5, const StringHolder& s6, const StringHolder& s5, const StringHolder& s6,
const StringHolder& s7) { const StringHolder& s7) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + s7.Length() + 1);
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
result += s7;
return result;
return absl::StrCat(s1, s2, s3, s4, s5, s6, s7);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
@ -294,16 +190,7 @@ string StrCat(const StringHolder& s1, const StringHolder& s2,
string result; string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() + result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + s7.Length() + s8.Length() + 1); s5.Length() + s6.Length() + s7.Length() + s8.Length() + 1);
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
result += s7;
result += s8;
return result;
return absl::StrCat(s1, s2, s3, s4, s5, s6, s7, s8);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
@ -311,21 +198,7 @@ string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s5, const StringHolder& s6, const StringHolder& s5, const StringHolder& s6,
const StringHolder& s7, const StringHolder& s8, const StringHolder& s7, const StringHolder& s8,
const StringHolder& s9) { const StringHolder& s9) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + s7.Length() + s8.Length() +
s9.Length() + 1);
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
result += s7;
result += s8;
result += s9;
return result;
return absl::StrCat(s1, s2, s3, s4, s5, s6, s7, s8, s9);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
@ -334,23 +207,7 @@ string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s7, const StringHolder& s8, const StringHolder& s7, const StringHolder& s8,
const StringHolder& s9, const StringHolder& s10, const StringHolder& s9, const StringHolder& s10,
const StringHolder& s11) { const StringHolder& s11) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + s7.Length() + s8.Length() +
s9.Length() + s10.Length() + s11.Length());
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
result += s7;
result += s8;
result += s9;
result += s10;
result += s11;
return result;
return absl::StrCat(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
@ -359,24 +216,7 @@ string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s7, const StringHolder& s8, const StringHolder& s7, const StringHolder& s8,
const StringHolder& s9, const StringHolder& s10, const StringHolder& s9, const StringHolder& s10,
const StringHolder& s11, const StringHolder& s12) { const StringHolder& s11, const StringHolder& s12) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + s7.Length() + s8.Length() +
s9.Length() + s10.Length() + s11.Length() + s12.Length());
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
result += s7;
result += s8;
result += s9;
result += s10;
result += s11;
result += s12;
return result;
return absl::StrCat(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
@ -386,26 +226,8 @@ string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s9, const StringHolder& s10, const StringHolder& s9, const StringHolder& s10,
const StringHolder& s11, const StringHolder& s12, const StringHolder& s11, const StringHolder& s12,
const StringHolder& s13) { const StringHolder& s13) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + s7.Length() + s8.Length() +
s9.Length() + s10.Length() + s11.Length() + s12.Length() +
s13.Length());
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
result += s7;
result += s8;
result += s9;
result += s10;
result += s11;
result += s12;
result += s13;
return result;
return absl::StrCat(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12,
s13);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
@ -415,27 +237,8 @@ string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s9, const StringHolder& s10, const StringHolder& s9, const StringHolder& s10,
const StringHolder& s11, const StringHolder& s12, const StringHolder& s11, const StringHolder& s12,
const StringHolder& s13, const StringHolder& s14) { const StringHolder& s13, const StringHolder& s14) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + s7.Length() + s8.Length() +
s9.Length() + s10.Length() + s11.Length() + s12.Length() +
s13.Length() + s14.Length());
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
result += s7;
result += s8;
result += s9;
result += s10;
result += s11;
result += s12;
result += s13;
result += s14;
return result;
return absl::StrCat(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12,
s13, s14);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
@ -446,28 +249,8 @@ string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s11, const StringHolder& s12, const StringHolder& s11, const StringHolder& s12,
const StringHolder& s13, const StringHolder& s14, const StringHolder& s13, const StringHolder& s14,
const StringHolder& s15) { const StringHolder& s15) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + s7.Length() + s8.Length() +
s9.Length() + s10.Length() + s11.Length() + s12.Length() +
s13.Length() + s14.Length() + s15.Length());
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
result += s7;
result += s8;
result += s9;
result += s10;
result += s11;
result += s12;
result += s13;
result += s14;
result += s15;
return result;
return absl::StrCat(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12,
s13, s14, s15);
} }
string StrCat(const StringHolder& s1, const StringHolder& s2, string StrCat(const StringHolder& s1, const StringHolder& s2,
@ -478,83 +261,35 @@ string StrCat(const StringHolder& s1, const StringHolder& s2,
const StringHolder& s11, const StringHolder& s12, const StringHolder& s11, const StringHolder& s12,
const StringHolder& s13, const StringHolder& s14, const StringHolder& s13, const StringHolder& s14,
const StringHolder& s15, const StringHolder& s16) { const StringHolder& s15, const StringHolder& s16) {
string result;
result.reserve(s1.Length() + s2.Length() + s3.Length() + s4.Length() +
s5.Length() + s6.Length() + s7.Length() + s8.Length() +
s9.Length() + s10.Length() + s11.Length() + s12.Length() +
s13.Length() + s14.Length() + s15.Length() + s16.Length());
result += s1;
result += s2;
result += s3;
result += s4;
result += s5;
result += s6;
result += s7;
result += s8;
result += s9;
result += s10;
result += s11;
result += s12;
result += s13;
result += s14;
result += s15;
result += s16;
return result;
return absl::StrCat(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12,
s13, s14, s15, s16);
} }
// StrAppend // StrAppend
void StrAppend(string* dest, const StringHolder& s1) { void StrAppend(string* dest, const StringHolder& s1) {
assert(dest);
dest->reserve(dest->length() + s1.Length() + 1);
*dest += s1;
absl::StrAppend(dest, s1);
} }
void StrAppend(string* dest, const StringHolder& s1, const StringHolder& s2) { void StrAppend(string* dest, const StringHolder& s1, const StringHolder& s2) {
assert(dest);
dest->reserve(dest->length() + s1.Length() + s2.Length() + 1);
*dest += s1;
*dest += s2;
absl::StrAppend(dest, s1, s2);
} }
void StrAppend(string* dest, const StringHolder& s1, const StringHolder& s2, void StrAppend(string* dest, const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3) { const StringHolder& s3) {
assert(dest);
dest->reserve(dest->length() + s1.Length() + s2.Length() + s3.Length() + 1);
*dest += s1;
*dest += s2;
*dest += s3;
absl::StrAppend(dest, s1, s2, s3);
} }
void StrAppend(string* dest, const StringHolder& s1, const StringHolder& s2, void StrAppend(string* dest, const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4) { const StringHolder& s3, const StringHolder& s4) {
assert(dest);
dest->reserve(dest->length() + s1.Length() + s2.Length() + s3.Length() +
s4.Length() + 1);
*dest += s1;
*dest += s2;
*dest += s3;
*dest += s4;
absl::StrAppend(dest, s1, s2, s3, s4);
} }
void StrAppend(string* dest, const StringHolder& s1, const StringHolder& s2, void StrAppend(string* dest, const StringHolder& s1, const StringHolder& s2,
const StringHolder& s3, const StringHolder& s4, const StringHolder& s3, const StringHolder& s4,
const StringHolder& s5) { const StringHolder& s5) {
assert(dest);
dest->reserve(dest->length() + s1.Length() + s2.Length() + s3.Length() +
s4.Length() + s5.Length() + 1);
*dest += s1;
*dest += s2;
*dest += s3;
*dest += s4;
*dest += s5;
absl::StrAppend(dest, s1, s2, s3, s4, s5);
} }
} // namespace phonenumbers } // namespace phonenumbers
} // namespace i18n
} // namespace i18n

+ 10
- 18
cpp/src/phonenumbers/stringutil.h View File

@ -22,6 +22,8 @@
#include <vector> #include <vector>
#include "phonenumbers/base/basictypes.h" #include "phonenumbers/base/basictypes.h"
#include "absl/strings/string_view.h"
#include "absl/strings/str_cat.h"
namespace i18n { namespace i18n {
namespace phonenumbers { namespace phonenumbers {
@ -46,13 +48,9 @@ size_t FindNth(const string& s, char c, int n);
// Splits a string using a character delimiter. Appends the components to the // Splits a string using a character delimiter. Appends the components to the
// provided vector. Note that empty tokens are ignored. // provided vector. Note that empty tokens are ignored.
void SplitStringUsing(const string& s, const string& delimiter,
void SplitStringUsing(const string& s, char delimiter,
vector<string>* result); vector<string>* result);
// Replaces any occurrence of the character 'remove' (or the characters
// in 'remove') with the character 'replacewith'.
void StripString(string* s, const char* remove, char replacewith);
// Returns true if 'in' starts with 'prefix' and writes 'in' minus 'prefix' into // Returns true if 'in' starts with 'prefix' and writes 'in' minus 'prefix' into
// 'out'. // 'out'.
bool TryStripPrefixString(const string& in, const string& prefix, string* out); bool TryStripPrefixString(const string& in, const string& prefix, string* out);
@ -77,9 +75,9 @@ void strrmm(string* s, const string& chars);
int GlobalReplaceSubstring(const string& substring, const string& replacement, int GlobalReplaceSubstring(const string& substring, const string& replacement,
string* s); string* s);
// Holds a reference to a std::string or C string. It can also be constructed
// from an integer which is converted to a string.
class StringHolder {
// An abstract to absl::AlphaNum type; AlphaNum has more accomidating
// constructors for more types.
class StringHolder: public absl::AlphaNum {
public: public:
// Don't make the constructors explicit to make the StrCat usage convenient. // Don't make the constructors explicit to make the StrCat usage convenient.
StringHolder(const string& s); // NOLINT(runtime/explicit) StringHolder(const string& s); // NOLINT(runtime/explicit)
@ -87,23 +85,17 @@ class StringHolder {
StringHolder(uint64 n); // NOLINT(runtime/explicit) StringHolder(uint64 n); // NOLINT(runtime/explicit)
~StringHolder(); ~StringHolder();
const string* GetString() const {
return string_;
const absl::string_view GetString() const {
return Piece();
} }
const char* GetCString() const { const char* GetCString() const {
return cstring_;
return data();
} }
size_t Length() const { size_t Length() const {
return len_;
return size();
} }
private:
const string converted_string_; // Stores the string converted from integer.
const string* const string_;
const char* const cstring_;
const size_t len_;
}; };
string& operator+=(string& lhs, const StringHolder& rhs); string& operator+=(string& lhs, const StringHolder& rhs);


+ 8
- 17
cpp/test/phonenumbers/stringutil_test.cc View File

@ -60,19 +60,13 @@ TEST(StringUtilTest, FindNth) {
TEST(StringUtilTest, SplitStringUsingWithEmptyString) { TEST(StringUtilTest, SplitStringUsingWithEmptyString) {
vector<string> result; vector<string> result;
SplitStringUsing("", ":", &result);
EXPECT_EQ(0U, result.size());
}
TEST(StringUtilTest, SplitStringUsingWithEmptyDelimiter) {
vector<string> result;
SplitStringUsing("hello", "", &result);
SplitStringUsing("", ':', &result);
EXPECT_EQ(0U, result.size()); EXPECT_EQ(0U, result.size());
} }
TEST(StringUtilTest, SplitStringUsing) { TEST(StringUtilTest, SplitStringUsing) {
vector<string> result; vector<string> result;
SplitStringUsing(":hello:world:", ":", &result);
SplitStringUsing(":hello:world:", ':', &result);
EXPECT_EQ(2U, result.size()); EXPECT_EQ(2U, result.size());
EXPECT_EQ("hello", result[0]); EXPECT_EQ("hello", result[0]);
EXPECT_EQ("world", result[1]); EXPECT_EQ("world", result[1]);
@ -80,7 +74,7 @@ TEST(StringUtilTest, SplitStringUsing) {
TEST(StringUtilTest, SplitStringUsingIgnoresEmptyToken) { TEST(StringUtilTest, SplitStringUsingIgnoresEmptyToken) {
vector<string> result; vector<string> result;
SplitStringUsing("hello::world", ":", &result);
SplitStringUsing("hello::world", ':', &result);
EXPECT_EQ(2U, result.size()); EXPECT_EQ(2U, result.size());
EXPECT_EQ("hello", result[0]); EXPECT_EQ("hello", result[0]);
EXPECT_EQ("world", result[1]); EXPECT_EQ("world", result[1]);
@ -195,13 +189,11 @@ TEST(StringUtilTest, StringHolder) {
static const char cstring[] = "aaa"; static const char cstring[] = "aaa";
StringHolder sh1(cstring); StringHolder sh1(cstring);
EXPECT_EQ(cstring, sh1.GetCString()); EXPECT_EQ(cstring, sh1.GetCString());
EXPECT_EQ(NULL, sh1.GetString());
// Test with std::string.
string s = "bbb";
// Test with absl::string_view.
string s = "aaa";
StringHolder sh2(s); StringHolder sh2(s);
EXPECT_EQ(NULL, sh2.GetCString());
EXPECT_EQ(&s, sh2.GetString());
EXPECT_EQ(cstring, sh2.GetString());
// Test GetLength(). // Test GetLength().
string s2 = "hello"; string s2 = "hello";
@ -210,9 +202,8 @@ TEST(StringUtilTest, StringHolder) {
// Test with uint64. // Test with uint64.
StringHolder sh4(42); StringHolder sh4(42);
EXPECT_TRUE(sh4.GetCString() == NULL);
EXPECT_EQ(2U, sh4.Length());
EXPECT_EQ("42", *sh4.GetString());
static const char cstring2[] = "42";;
EXPECT_EQ(cstring2, sh4.GetString());
} }
// Test the operator+=(string& lhs, const StringHolder& rhs) implementation. // Test the operator+=(string& lhs, const StringHolder& rhs) implementation.


+ 2
- 2
tools/cpp/CMakeLists.txt View File

@ -64,7 +64,7 @@ endif ()
include_directories ("src") include_directories ("src")
add_executable (generate_geocoding_data ${SOURCES}) add_executable (generate_geocoding_data ${SOURCES})
target_link_libraries (generate_geocoding_data absl::strings absl::btree)
target_link_libraries (generate_geocoding_data absl::strings absl::btree absl::node_hash_set)
set (TEST_SOURCES set (TEST_SOURCES
"src/cpp-build/generate_geocoding_data.cc" "src/cpp-build/generate_geocoding_data.cc"
@ -81,4 +81,4 @@ endif ()
# Build the testing binary. # Build the testing binary.
include_directories ("test") include_directories ("test")
add_executable (generate_geocoding_data_test ${TEST_SOURCES}) add_executable (generate_geocoding_data_test ${TEST_SOURCES})
target_link_libraries (generate_geocoding_data_test absl::btree ${TEST_LIBS})
target_link_libraries (generate_geocoding_data_test absl::btree ${TEST_LIBS} absl::node_hash_set)

Loading…
Cancel
Save