OutStringType DoReplaceStringPlaceholders(const FormatStringType& format_string, const std::vector<OutStringType>& subst, std::vector<size_t>* offsets) { size_t substitutions = subst.size(); size_t sub_length = 0; for (typename std::vector<OutStringType>::const_iterator iter = subst.begin(); iter != subst.end(); ++iter) { sub_length += iter->length(); } OutStringType formatted; formatted.reserve(format_string.length() + sub_length); std::vector<ReplacementOffset> r_offsets; for (typename FormatStringType::const_iterator i = format_string.begin(); i != format_string.end(); ++i) { if ('$' == *i) { if (i + 1 != format_string.end()) { ++i; DCHECK('$' == *i || '1' <= *i) << "Invalid placeholder: " << *i; if ('$' == *i) { while (i != format_string.end() && '$' == *i) { formatted.push_back('$'); ++i; } --i; } else { uintptr_t index = 0; while (i != format_string.end() && '0' <= *i && *i <= '9') { index *= 10; index += *i - '0'; ++i; } --i; index -= 1; if (offsets) { ReplacementOffset r_offset(index, static_cast<int>(formatted.size())); r_offsets.insert(std::lower_bound(r_offsets.begin(), r_offsets.end(), r_offset, &CompareParameter), r_offset); } if (index < substitutions) formatted.append(subst.at(index)); } } } else { formatted.push_back(*i); } } if (offsets) { for (std::vector<ReplacementOffset>::const_iterator i = r_offsets.begin(); i != r_offsets.end(); ++i) { offsets->push_back(i->offset); } } return formatted; }