str_replace.cc
Go to the documentation of this file.
00001 // Copyright 2017 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 #include "absl/strings/str_replace.h"
00016 
00017 #include "absl/strings/str_cat.h"
00018 
00019 namespace absl {
00020 namespace strings_internal {
00021 
00022 using FixedMapping =
00023     std::initializer_list<std::pair<absl::string_view, absl::string_view>>;
00024 
00025 // Applies the ViableSubstitutions in subs_ptr to the absl::string_view s, and
00026 // stores the result in *result_ptr. Returns the number of substitutions that
00027 // occurred.
00028 int ApplySubstitutions(
00029     absl::string_view s,
00030     std::vector<strings_internal::ViableSubstitution>* subs_ptr,
00031     std::string* result_ptr) {
00032   auto& subs = *subs_ptr;
00033   int substitutions = 0;
00034   size_t pos = 0;
00035   while (!subs.empty()) {
00036     auto& sub = subs.back();
00037     if (sub.offset >= pos) {
00038       if (pos <= s.size()) {
00039         StrAppend(result_ptr, s.substr(pos, sub.offset - pos), sub.replacement);
00040       }
00041       pos = sub.offset + sub.old.size();
00042       substitutions += 1;
00043     }
00044     sub.offset = s.find(sub.old, pos);
00045     if (sub.offset == s.npos) {
00046       subs.pop_back();
00047     } else {
00048       // Insertion sort to ensure the last ViableSubstitution continues to be
00049       // before all the others.
00050       size_t index = subs.size();
00051       while (--index && subs[index - 1].OccursBefore(subs[index])) {
00052         std::swap(subs[index], subs[index - 1]);
00053       }
00054     }
00055   }
00056   result_ptr->append(s.data() + pos, s.size() - pos);
00057   return substitutions;
00058 }
00059 
00060 }  // namespace strings_internal
00061 
00062 // We can implement this in terms of the generic StrReplaceAll, but
00063 // we must specify the template overload because C++ cannot deduce the type
00064 // of an initializer_list parameter to a function, and also if we don't specify
00065 // the type, we just call ourselves.
00066 //
00067 // Note that we implement them here, rather than in the header, so that they
00068 // aren't inlined.
00069 
00070 std::string StrReplaceAll(absl::string_view s,
00071                           strings_internal::FixedMapping replacements) {
00072   return StrReplaceAll<strings_internal::FixedMapping>(s, replacements);
00073 }
00074 
00075 int StrReplaceAll(strings_internal::FixedMapping replacements,
00076                   std::string* target) {
00077   return StrReplaceAll<strings_internal::FixedMapping>(replacements, target);
00078 }
00079 
00080 }  // namespace absl


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:15