1#include <c10/util/StringUtil.h>
2
3#include <cstring>
4#include <string>
5
6namespace c10 {
7
8namespace detail {
9
10std::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
20std::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
30std::ostream& operator<<(std::ostream& out, const SourceLocation& loc) {
31 out << loc.function << " at " << loc.file << ":" << loc.line;
32 return out;
33}
34
35size_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