69 |
72 |
70 return result; |
73 return result; |
71 } |
74 } |
72 |
75 |
73 /*! |
76 /*! |
74 * \brief Modifies the given index so that if it is negative, it is translated into a positive index starting from the |
77 * \brief Extracts a substring from the middle of the given string |
75 * end of the string. For example, an index of -1 will be modified to point to the last character in the string, |
78 * \param str string to extract from |
76 * -2 to the second last, etc. |
79 * \param rangeBegin starting index of the substring |
77 * \param index Index to translate. |
80 * \param rangeEnd end index of the substring |
78 */ |
81 * \return substring |
79 inline void modifyIndex(const std::string& str, int& index) |
|
80 { |
|
81 if (index < 0) |
|
82 index = str.length() - index; |
|
83 } |
|
84 |
|
85 /*! |
|
86 * \param a Starting index of the range. |
|
87 * \param b Ending index of the range. |
|
88 * \returns a sub-string containing all characters from \c a to \c b, not including the character at \c b. |
|
89 */ |
82 */ |
90 std::string mid(const std::string& str, int rangeBegin, int rangeEnd) |
83 std::string mid(const std::string& str, int rangeBegin, int rangeEnd) |
91 { |
84 { |
92 modifyIndex(str, rangeBegin); |
|
93 modifyIndex(str, rangeEnd); |
|
94 rangeBegin = max(rangeBegin, 0); |
85 rangeBegin = max(rangeBegin, 0); |
95 rangeEnd = min(rangeEnd, static_cast<signed>(str.length())); |
86 rangeEnd = min(rangeEnd, static_cast<signed>(str.length())); |
96 |
87 std::string result; |
97 if (rangeEnd <= rangeBegin) |
88 if (rangeEnd > rangeBegin) |
98 return ""; |
89 { |
99 else |
90 result = str.substr(rangeBegin, rangeEnd - rangeBegin); |
100 return str.substr(rangeBegin, rangeEnd - rangeBegin); |
91 } |
101 } |
92 return result; |
102 |
93 } |
103 /*! |
94 |
104 * \param length Amount of characters to return. |
95 /*! |
105 * \returns the \c length right-most characters of the string. |
96 * \brief right Extracts a substring from the end of the substring |
|
97 * \param str string to extract from |
|
98 * \param length desired length of the new substring |
|
99 * \return substring |
106 */ |
100 */ |
107 std::string right(const std::string& str, int length) |
101 std::string right(const std::string& str, int length) |
108 { |
102 { |
109 if (length >= static_cast<signed>(str.length())) |
103 if (length >= static_cast<signed>(str.length())) |
110 return str; |
104 return str; |
111 else |
105 else |
112 return std::string{str.data() + str.length() - length}; |
106 return std::string{str.data() + str.length() - length}; |
113 } |
107 } |
114 |
108 |
115 /*! |
109 /*! |
116 * \brief Formats this string using \c vsnprintf, using the provided arguments. |
110 * \brief Formats a string using \c vsnprintf, using a va_list argument list |
117 * \param formatString Template string to use with formatting. |
111 * \param formatString formatting string |
118 * \param args Variadic arguments to use with formatting. |
112 * \param args argument list |
|
113 * \return formatted string |
119 */ |
114 */ |
120 std::string vsprintf(const char* formatString, va_list args) |
115 std::string vsprintf(const char* formatString, va_list args) |
121 { |
116 { |
122 std::string result; |
117 std::string result; |
123 |
|
124 // Copy the argument list so that we have something to provide to vsnprintf in case we have to call it again. |
118 // Copy the argument list so that we have something to provide to vsnprintf in case we have to call it again. |
125 va_list argsCopy; |
119 va_list argsCopy; |
126 va_copy(argsCopy, args); |
120 va_copy(argsCopy, args); |
127 |
|
128 // First, attempt to format using a fixed-size buffer. |
121 // First, attempt to format using a fixed-size buffer. |
129 static char buffer[1024]; |
122 static char buffer[1024]; |
130 size_t length = vsnprintf(buffer, sizeof buffer, formatString, args); |
123 const std::size_t length = std::vsnprintf(buffer, countof(buffer), formatString, args); |
131 |
|
132 if (length < sizeof buffer) |
124 if (length < sizeof buffer) |
133 { |
125 { |
134 // vsnprintf succeeded in fitting the formatted string into the buffer, so we're done. |
126 // vsnprintf succeeded in fitting the formatted string into the buffer, so we're done. |
135 result = buffer; |
127 result = buffer; |
136 } |
128 } |
137 else |
129 else |
138 { |
130 { |
139 // vsnprintf needs more space, so we have to allocate a new buffer and try again. |
131 // vsnprintf needs more space, so we have to allocate a new buffer and try again. |
140 std::vector<char> newBuffer(length + 1); |
132 result.resize(length + 1); |
141 vsnprintf(newBuffer.data(), length + 1, formatString, argsCopy); |
133 std::vsnprintf(result.data(), length + 1, formatString, argsCopy); |
142 result = newBuffer.data(); |
134 } |
143 } |
135 return result; |
144 |
136 } |
145 return result; |
137 |
146 } |
138 /*! |
147 |
139 * \brief Formats a string using \c printf -like syntax |
148 /*! |
140 * \param formatString formatting string |
149 * \brief Formats this string using \c printf -like syntax. |
141 * \param ... printf-like arguments |
150 * \param formatString Template string to use with formatting. |
142 * \return formatted string |
151 * \param ... Variadic arguments to use with formatting. |
|
152 */ |
143 */ |
153 std::string __cdecl sprintf(const char* formatString, ...) |
144 std::string __cdecl sprintf(const char* formatString, ...) |
154 { |
145 { |
155 va_list args; |
146 va_list args; |
156 va_start (args, formatString); |
147 va_start (args, formatString); |
157 std::string result = vsprintf(formatString, args); |
148 std::string result = vsprintf(formatString, args); |
158 va_end (args); |
149 va_end (args); |
159 return result; |
150 return result; |
160 } |
151 } |
161 |
152 |
|
153 /*! |
|
154 * \brief Removes a substring from the middle of a string |
|
155 * \param string original string |
|
156 * \param start start index to remove |
|
157 * \param end end index to remove |
|
158 * \return modified string |
|
159 */ |
162 std::string remove_range(const std::string &string, int start, int end) |
160 std::string remove_range(const std::string &string, int start, int end) |
163 { |
161 { |
164 std::string result; |
162 std::string result; |
165 result.reserve(string.length() - (end - start)); |
163 result.reserve(string.length() - (end - start)); |
166 std::copy(string.begin(), string.begin() + start, std::back_inserter(result)); |
164 std::copy(string.begin(), string.begin() + start, std::back_inserter(result)); |
167 std::copy(string.begin() + end, string.end(), std::back_inserter(result)); |
165 std::copy(string.begin() + end, string.end(), std::back_inserter(result)); |
168 return result; |
166 return result; |
169 } |
167 } |
170 |
168 |
171 |
169 /*! |
172 /*! |
170 * \brief Finds out whether the specified string starts with the specified substring. |
173 * \param other Sub-string to find from the beginning of this string. |
171 * \param string string to test |
174 * \returns whether or not this string begins with the provided sub-string. |
172 * \param substring substring to look for |
175 */ |
173 * \return bool |
176 bool starts_with(const std::string& str, const std::string& other) |
174 */ |
177 { |
175 bool starts_with(const std::string& string, const std::string& substring) |
178 if (str.length() < other.length()) |
176 { |
|
177 if (string.length() < substring.length()) |
179 return false; |
178 return false; |
180 else |
179 else |
181 return std::strncmp(str.data(), other.data(), other.length()) == 0; |
180 return std::strncmp(string.data(), substring.data(), substring.length()) == 0; |
182 } |
181 } |
183 |
182 |
184 /*! |
183 /*! |
185 * \brief Replaces all instances of \c text with \c replacement. |
184 * \brief Replaces all instances of \c text with \c replacement in place. |
186 * \param text Text to replace away. |
185 * \param text Text to replace away. |
187 * \param replacement Text to replace \c text with. |
186 * \param replacement Text to replace \c text with. |
188 */ |
187 */ |
189 void replace_all(std::string& str, const char* text, const char* replacement) |
188 void replace_all(std::string& str, const char* text, const char* replacement) |
190 { |
189 { |