diff options
author | anastasy888 <anastasy888@yandex-team.ru> | 2022-02-10 16:45:54 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:54 +0300 |
commit | 49f765d71da452ea93138a25559dfa68dd76c7f3 (patch) | |
tree | 1016041feb637349e401dcc0fa85217dd2c2c639 /contrib/restricted/abseil-cpp/absl/strings/str_replace.h | |
parent | 7353a3fdea9c67c256980c00a2b3b67f09b23a27 (diff) | |
download | ydb-49f765d71da452ea93138a25559dfa68dd76c7f3.tar.gz |
Restoring authorship annotation for <anastasy888@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/restricted/abseil-cpp/absl/strings/str_replace.h')
-rw-r--r-- | contrib/restricted/abseil-cpp/absl/strings/str_replace.h | 434 |
1 files changed, 217 insertions, 217 deletions
diff --git a/contrib/restricted/abseil-cpp/absl/strings/str_replace.h b/contrib/restricted/abseil-cpp/absl/strings/str_replace.h index 273c707735..cf0cb0b282 100644 --- a/contrib/restricted/abseil-cpp/absl/strings/str_replace.h +++ b/contrib/restricted/abseil-cpp/absl/strings/str_replace.h @@ -1,219 +1,219 @@ -// -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ----------------------------------------------------------------------------- -// File: str_replace.h -// ----------------------------------------------------------------------------- -// -// This file defines `absl::StrReplaceAll()`, a general-purpose string -// replacement function designed for large, arbitrary text substitutions, -// especially on strings which you are receiving from some other system for -// further processing (e.g. processing regular expressions, escaping HTML -// entities, etc.). `StrReplaceAll` is designed to be efficient even when only -// one substitution is being performed, or when substitution is rare. -// -// If the string being modified is known at compile-time, and the substitutions -// vary, `absl::Substitute()` may be a better choice. -// -// Example: -// -// std::string html_escaped = absl::StrReplaceAll(user_input, { -// {"&", "&"}, -// {"<", "<"}, -// {">", ">"}, -// {"\"", """}, -// {"'", "'"}}); -#ifndef ABSL_STRINGS_STR_REPLACE_H_ -#define ABSL_STRINGS_STR_REPLACE_H_ - -#include <string> -#include <utility> -#include <vector> - -#include "absl/base/attributes.h" -#include "absl/strings/string_view.h" - -namespace absl { +// +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: str_replace.h +// ----------------------------------------------------------------------------- +// +// This file defines `absl::StrReplaceAll()`, a general-purpose string +// replacement function designed for large, arbitrary text substitutions, +// especially on strings which you are receiving from some other system for +// further processing (e.g. processing regular expressions, escaping HTML +// entities, etc.). `StrReplaceAll` is designed to be efficient even when only +// one substitution is being performed, or when substitution is rare. +// +// If the string being modified is known at compile-time, and the substitutions +// vary, `absl::Substitute()` may be a better choice. +// +// Example: +// +// std::string html_escaped = absl::StrReplaceAll(user_input, { +// {"&", "&"}, +// {"<", "<"}, +// {">", ">"}, +// {"\"", """}, +// {"'", "'"}}); +#ifndef ABSL_STRINGS_STR_REPLACE_H_ +#define ABSL_STRINGS_STR_REPLACE_H_ + +#include <string> +#include <utility> +#include <vector> + +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" + +namespace absl { ABSL_NAMESPACE_BEGIN - -// StrReplaceAll() -// -// Replaces character sequences within a given string with replacements provided -// within an initializer list of key/value pairs. Candidate replacements are -// considered in order as they occur within the string, with earlier matches -// taking precedence, and longer matches taking precedence for candidates -// starting at the same position in the string. Once a substitution is made, the -// replaced text is not considered for any further substitutions. -// -// Example: -// -// std::string s = absl::StrReplaceAll( -// "$who bought $count #Noun. Thanks $who!", -// {{"$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, - std::initializer_list<std::pair<absl::string_view, absl::string_view>> - replacements); - -// Overload of `StrReplaceAll()` to accept a container of key/value replacement -// pairs (typically either an associative map or a `std::vector` of `std::pair` -// elements). A vector of pairs is generally more efficient. -// -// Examples: -// -// std::map<const absl::string_view, const absl::string_view> replacements; -// replacements["$who"] = "Bob"; -// replacements["$count"] = "5"; -// replacements["#Noun"] = "Apples"; -// 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, std::string>> replacements; -// replacements.push_back({"&", "&"}); -// replacements.push_back({"<", "<"}); -// replacements.push_back({">", ">"}); -// std::string s = absl::StrReplaceAll("if (ptr < &foo)", -// replacements); -// EXPECT_EQ("if (ptr < &foo)", s); -template <typename StrToStrMapping> -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 -// list of key/value pairs, returning the number of substitutions that occurred. -// -// Example: -// -// std::string s = std::string("$who bought $count #Noun. Thanks $who!"); -// int count; -// count = absl::StrReplaceAll({{"$count", absl::StrCat(5)}, -// {"$who", "Bob"}, -// {"#Noun", "Apples"}}, &s); -// EXPECT_EQ(count, 4); -// EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s); -int StrReplaceAll( - std::initializer_list<std::pair<absl::string_view, absl::string_view>> - replacements, - std::string* target); - -// Overload of `StrReplaceAll()` to replace patterns within a given output -// string *in place* with replacements provided within a container of key/value -// pairs. -// -// Example: -// -// std::string s = std::string("if (ptr < &foo)"); -// int count = absl::StrReplaceAll({{"&", "&"}, -// {"<", "<"}, -// {">", ">"}}, &s); -// EXPECT_EQ(count, 2); -// EXPECT_EQ("if (ptr < &foo)", s); -template <typename StrToStrMapping> -int StrReplaceAll(const StrToStrMapping& replacements, std::string* target); - -// Implementation details only, past this point. -namespace strings_internal { - -struct ViableSubstitution { - absl::string_view old; - absl::string_view replacement; - size_t offset; - - ViableSubstitution(absl::string_view old_str, - absl::string_view replacement_str, size_t offset_val) - : old(old_str), replacement(replacement_str), offset(offset_val) {} - - // One substitution occurs "before" another (takes priority) if either - // it has the lowest offset, or it has the same offset but a larger size. - bool OccursBefore(const ViableSubstitution& y) const { - if (offset != y.offset) return offset < y.offset; - return old.size() > y.old.size(); - } -}; - -// Build a vector of ViableSubstitutions based on the given list of -// replacements. subs can be implemented as a priority_queue. However, it turns -// out that most callers have small enough a list of substitutions that the -// overhead of such a queue isn't worth it. -template <typename StrToStrMapping> -std::vector<ViableSubstitution> FindSubstitutions( - absl::string_view s, const StrToStrMapping& replacements) { - std::vector<ViableSubstitution> subs; - subs.reserve(replacements.size()); - - for (const auto& rep : replacements) { - using std::get; - absl::string_view old(get<0>(rep)); - - size_t pos = s.find(old); - if (pos == s.npos) continue; - - // Ignore attempts to replace "". This condition is almost never true, - // but above condition is frequently true. That's why we test for this - // now and not before. - if (old.empty()) continue; - - subs.emplace_back(old, get<1>(rep), pos); - - // Insertion sort to ensure the last ViableSubstitution comes before - // all the others. - size_t index = subs.size(); - while (--index && subs[index - 1].OccursBefore(subs[index])) { - std::swap(subs[index], subs[index - 1]); - } - } - return subs; -} - -int ApplySubstitutions(absl::string_view s, - std::vector<ViableSubstitution>* subs_ptr, - std::string* result_ptr); - -} // namespace strings_internal - -template <typename StrToStrMapping> -std::string StrReplaceAll(absl::string_view s, - const StrToStrMapping& replacements) { - auto subs = strings_internal::FindSubstitutions(s, replacements); - std::string result; - result.reserve(s.size()); - strings_internal::ApplySubstitutions(s, &subs, &result); - return result; -} - -template <typename StrToStrMapping> -int StrReplaceAll(const StrToStrMapping& replacements, std::string* target) { - auto subs = strings_internal::FindSubstitutions(*target, replacements); - if (subs.empty()) return 0; - - std::string result; - result.reserve(target->size()); - int substitutions = - strings_internal::ApplySubstitutions(*target, &subs, &result); - target->swap(result); - return substitutions; -} - + +// StrReplaceAll() +// +// Replaces character sequences within a given string with replacements provided +// within an initializer list of key/value pairs. Candidate replacements are +// considered in order as they occur within the string, with earlier matches +// taking precedence, and longer matches taking precedence for candidates +// starting at the same position in the string. Once a substitution is made, the +// replaced text is not considered for any further substitutions. +// +// Example: +// +// std::string s = absl::StrReplaceAll( +// "$who bought $count #Noun. Thanks $who!", +// {{"$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, + std::initializer_list<std::pair<absl::string_view, absl::string_view>> + replacements); + +// Overload of `StrReplaceAll()` to accept a container of key/value replacement +// pairs (typically either an associative map or a `std::vector` of `std::pair` +// elements). A vector of pairs is generally more efficient. +// +// Examples: +// +// std::map<const absl::string_view, const absl::string_view> replacements; +// replacements["$who"] = "Bob"; +// replacements["$count"] = "5"; +// replacements["#Noun"] = "Apples"; +// 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, std::string>> replacements; +// replacements.push_back({"&", "&"}); +// replacements.push_back({"<", "<"}); +// replacements.push_back({">", ">"}); +// std::string s = absl::StrReplaceAll("if (ptr < &foo)", +// replacements); +// EXPECT_EQ("if (ptr < &foo)", s); +template <typename StrToStrMapping> +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 +// list of key/value pairs, returning the number of substitutions that occurred. +// +// Example: +// +// std::string s = std::string("$who bought $count #Noun. Thanks $who!"); +// int count; +// count = absl::StrReplaceAll({{"$count", absl::StrCat(5)}, +// {"$who", "Bob"}, +// {"#Noun", "Apples"}}, &s); +// EXPECT_EQ(count, 4); +// EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s); +int StrReplaceAll( + std::initializer_list<std::pair<absl::string_view, absl::string_view>> + replacements, + std::string* target); + +// Overload of `StrReplaceAll()` to replace patterns within a given output +// string *in place* with replacements provided within a container of key/value +// pairs. +// +// Example: +// +// std::string s = std::string("if (ptr < &foo)"); +// int count = absl::StrReplaceAll({{"&", "&"}, +// {"<", "<"}, +// {">", ">"}}, &s); +// EXPECT_EQ(count, 2); +// EXPECT_EQ("if (ptr < &foo)", s); +template <typename StrToStrMapping> +int StrReplaceAll(const StrToStrMapping& replacements, std::string* target); + +// Implementation details only, past this point. +namespace strings_internal { + +struct ViableSubstitution { + absl::string_view old; + absl::string_view replacement; + size_t offset; + + ViableSubstitution(absl::string_view old_str, + absl::string_view replacement_str, size_t offset_val) + : old(old_str), replacement(replacement_str), offset(offset_val) {} + + // One substitution occurs "before" another (takes priority) if either + // it has the lowest offset, or it has the same offset but a larger size. + bool OccursBefore(const ViableSubstitution& y) const { + if (offset != y.offset) return offset < y.offset; + return old.size() > y.old.size(); + } +}; + +// Build a vector of ViableSubstitutions based on the given list of +// replacements. subs can be implemented as a priority_queue. However, it turns +// out that most callers have small enough a list of substitutions that the +// overhead of such a queue isn't worth it. +template <typename StrToStrMapping> +std::vector<ViableSubstitution> FindSubstitutions( + absl::string_view s, const StrToStrMapping& replacements) { + std::vector<ViableSubstitution> subs; + subs.reserve(replacements.size()); + + for (const auto& rep : replacements) { + using std::get; + absl::string_view old(get<0>(rep)); + + size_t pos = s.find(old); + if (pos == s.npos) continue; + + // Ignore attempts to replace "". This condition is almost never true, + // but above condition is frequently true. That's why we test for this + // now and not before. + if (old.empty()) continue; + + subs.emplace_back(old, get<1>(rep), pos); + + // Insertion sort to ensure the last ViableSubstitution comes before + // all the others. + size_t index = subs.size(); + while (--index && subs[index - 1].OccursBefore(subs[index])) { + std::swap(subs[index], subs[index - 1]); + } + } + return subs; +} + +int ApplySubstitutions(absl::string_view s, + std::vector<ViableSubstitution>* subs_ptr, + std::string* result_ptr); + +} // namespace strings_internal + +template <typename StrToStrMapping> +std::string StrReplaceAll(absl::string_view s, + const StrToStrMapping& replacements) { + auto subs = strings_internal::FindSubstitutions(s, replacements); + std::string result; + result.reserve(s.size()); + strings_internal::ApplySubstitutions(s, &subs, &result); + return result; +} + +template <typename StrToStrMapping> +int StrReplaceAll(const StrToStrMapping& replacements, std::string* target) { + auto subs = strings_internal::FindSubstitutions(*target, replacements); + if (subs.empty()) return 0; + + std::string result; + result.reserve(target->size()); + int substitutions = + strings_internal::ApplySubstitutions(*target, &subs, &result); + target->swap(result); + return substitutions; +} + ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_STRINGS_STR_REPLACE_H_ +} // namespace absl + +#endif // ABSL_STRINGS_STR_REPLACE_H_ |