1 | #include <c10/util/StringUtil.h> |
2 | |
3 | #include <cstring> |
4 | #include <string> |
5 | |
6 | namespace c10 { |
7 | |
8 | namespace detail { |
9 | |
10 | std::string StripBasename(const std::string& full_path) { |
11 | const char kSeparator = '/'; |
12 | size_t pos = full_path.rfind(kSeparator); |
13 | if (pos != std::string::npos) { |
14 | return full_path.substr(pos + 1, std::string::npos); |
15 | } else { |
16 | return full_path; |
17 | } |
18 | } |
19 | |
20 | std::string ExcludeFileExtension(const std::string& file_name) { |
21 | const char sep = '.'; |
22 | auto end_index = file_name.find_last_of(sep) == std::string::npos |
23 | ? -1 |
24 | : file_name.find_last_of(sep); |
25 | return file_name.substr(0, end_index); |
26 | } |
27 | |
28 | } // namespace detail |
29 | |
30 | std::ostream& operator<<(std::ostream& out, const SourceLocation& loc) { |
31 | out << loc.function << " at " << loc.file << ":" << loc.line; |
32 | return out; |
33 | } |
34 | |
35 | size_t ReplaceAll(std::string& s, c10::string_view from, c10::string_view to) { |
36 | if (from.empty()) { |
37 | return 0; |
38 | } |
39 | |
40 | size_t numReplaced = 0; |
41 | std::string::size_type last_pos = 0u; |
42 | std::string::size_type cur_pos = 0u; |
43 | std::string::size_type write_pos = 0u; |
44 | const c10::string_view input(s); |
45 | |
46 | if (from.size() >= to.size()) { |
47 | // If the replacement string is not larger than the original, we |
48 | // can do the replacement in-place without allocating new storage. |
49 | char* s_data = s.data(); |
50 | |
51 | while ((cur_pos = s.find(from.data(), last_pos, from.size())) != |
52 | std::string::npos) { |
53 | ++numReplaced; |
54 | // Append input between replaced sub-strings |
55 | if (write_pos != last_pos) { |
56 | std::copy(s_data + last_pos, s_data + cur_pos, s_data + write_pos); |
57 | } |
58 | write_pos += cur_pos - last_pos; |
59 | // Append the replacement sub-string |
60 | std::copy(to.begin(), to.end(), s_data + write_pos); |
61 | write_pos += to.size(); |
62 | // Start search from next character after `from` |
63 | last_pos = cur_pos + from.size(); |
64 | } |
65 | |
66 | // Append any remaining input after replaced sub-strings |
67 | if (write_pos != last_pos) { |
68 | std::copy(s_data + last_pos, s_data + input.size(), s_data + write_pos); |
69 | write_pos += input.size() - last_pos; |
70 | s.resize(write_pos); |
71 | } |
72 | return numReplaced; |
73 | } |
74 | |
75 | // Otherwise, do an out-of-place replacement in a temporary buffer |
76 | std::string buffer; |
77 | |
78 | while ((cur_pos = s.find(from.data(), last_pos, from.size())) != |
79 | std::string::npos) { |
80 | ++numReplaced; |
81 | // Append input between replaced sub-strings |
82 | buffer.append(input.begin() + last_pos, input.begin() + cur_pos); |
83 | // Append the replacement sub-string |
84 | buffer.append(to.begin(), to.end()); |
85 | // Start search from next character after `from` |
86 | last_pos = cur_pos + from.size(); |
87 | } |
88 | if (numReplaced == 0) { |
89 | // If nothing was replaced, don't modify the input |
90 | return 0; |
91 | } |
92 | // Append any remaining input after replaced sub-strings |
93 | buffer.append(input.begin() + last_pos, input.end()); |
94 | s = std::move(buffer); |
95 | return numReplaced; |
96 | } |
97 | |
98 | } // namespace c10 |
99 | |