Library of Assembled Shared Sources
extended_string.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43#include <locale>
44
45namespace lass
46{
47namespace stde
48{
49namespace impl
50{
51 template <typename StringType>
52 StringType whitespace(const StringType&)
53 {
54 return StringType(" \t\n");
55 }
56}
57
58/** @ingroup extended_string
59 * convert std::basic_string to lower case by using user locale
60 */
61template <typename Char, typename Traits, typename Alloc>
62std::basic_string<Char, Traits, Alloc>
63tolower(const std::basic_string<Char, Traits, Alloc>& input,
64 const std::locale& locale)
65{
66 std::basic_string<Char, Traits, Alloc> result(input);
67 typedef typename std::basic_string<Char, Traits, Alloc>::iterator iterator;
68 for (iterator i = result.begin(); i != result.end(); ++i)
69 {
70 *i = std::tolower<Char>(*i, locale);
71 }
72 return result;
73}
74
75
76
77/** @ingroup extended_string
78 * convert std::basic_string to upper case by using user locale
79 */
80template <typename Char, typename Traits, typename Alloc>
81std::basic_string<Char, Traits, Alloc>
82toupper(const std::basic_string<Char, Traits, Alloc>& input,
83 const std::locale& locale)
84{
85 std::basic_string<Char, Traits, Alloc> result(input);
86 typedef typename std::basic_string<Char, Traits, Alloc>::iterator iterator;
87 for (iterator i = result.begin(); i != result.end(); ++i)
88 {
89 *i = std::toupper<Char>(*i, locale);
90 }
91 return result;
92}
93
94/** @ingroup extended_string
95 * replace all instances of @a to_be_replaced in @a input by @a replacement.
96 */
97template <typename Char, typename Traits, typename Alloc>
98std::basic_string<Char, Traits, Alloc>
99replace_all(const std::basic_string<Char, Traits, Alloc>& input,
100 const std::basic_string<Char, Traits, Alloc>& to_be_replaced,
101 const std::basic_string<Char, Traits, Alloc>& replacement)
102{
103 typedef std::basic_string<Char, Traits, Alloc> string_type;
104 typename string_type::size_type size_to_be_replaced = to_be_replaced.size();
105 typename string_type::size_type size_replacement = replacement.size();
106 string_type result(input);
107
108 typename string_type::size_type i = result.find(to_be_replaced);
109 while (i != string_type::npos)
110 {
111 result.replace(i, size_to_be_replaced, replacement);
112 i = result.find(to_be_replaced, i + size_replacement);
113 }
114 return result;
115}
116
117/** @ingroup extended_string
118 * replace all instances of @a to_be_replaced in @a input by @a replacement.
119 */
120template <typename Char, typename Traits, typename Alloc>
121std::basic_string<Char, Traits, Alloc>
122replace_all(const std::basic_string<Char, Traits, Alloc>& input,
123 const Char* to_be_replaced,
124 const Char* replacement)
125{
126 typedef std::basic_string<Char, Traits, Alloc> string_type;
127 return replace_all(input, string_type(to_be_replaced), string_type(replacement));
128}
129
130
131
132/** @ingroup extended_string
133 * returns true if @a input begins with the input @a prefix
134 */
135template <typename Char, typename Traits, typename Alloc>
136bool begins_with(const std::basic_string<Char, Traits, Alloc>& input,
137 const std::basic_string<Char, Traits, Alloc>& prefix)
138{
139 return prefix.length() <= input.length() && std::equal(prefix.begin(), prefix.end(), input.begin());
140}
141
142/** @ingroup extended_string
143 * returns true if @a input begins with the input @a prefix
144 */
145template <typename Char, typename Traits, typename Alloc>
146bool begins_with(const std::basic_string<Char, Traits, Alloc>& input,
147 const Char* prefix)
148{
149 typedef std::basic_string<Char, Traits, Alloc> string_type;
150 return begins_with(input, string_type(prefix));
151}
152
153/** @ingroup extended_string
154 * returns true if @a input begins with the input @a prefix
155 */
156template <typename Char, typename Traits, typename Alloc>
157bool begins_with(const std::basic_string<Char, Traits, Alloc>& input,
158 Char prefix)
159{
160 return !input.empty() && input[0] == prefix;
161}
162
163
164
165/** @ingroup extended_string
166 * returns true if @a input ends with the input @a suffix
167 */
168template <typename Char, typename Traits, typename Alloc>
169bool ends_with(const std::basic_string<Char, Traits, Alloc>& input,
170 const std::basic_string<Char, Traits, Alloc>& suffix)
171{
172 typedef typename std::basic_string<Char, Traits, Alloc>::difference_type difference_type;
173 return suffix.length() <= input.length() &&
174 std::equal(suffix.begin(), suffix.end(), input.end() - static_cast<difference_type>(suffix.length()));
175}
176
177/** @ingroup extended_string
178 * returns true if @a input ends with the input @a suffix
179 */
180template <typename Char, typename Traits, typename Alloc>
181bool ends_with(const std::basic_string<Char, Traits, Alloc>& input,
182 const Char* suffix)
183{
184 typedef std::basic_string<Char, Traits, Alloc> string_type;
185 return ends_with(input, string_type(suffix));
186}
187
188/** @ingroup extended_string
189 * returns true if @a input ends with the input @a suffix
190 */
191template <typename Char, typename Traits, typename Alloc>
192bool ends_with(const std::basic_string<Char, Traits, Alloc>& input,
193 Char suffix)
194{
195 return !input.empty() && input[input.size()-1] == suffix;
196}
197
198
199
200/** @ingroup extended_string
201 * Reflects the Python function @c split without seperator argument
202 *
203 * Return a vector of the words of the string @a to_be_split. The words are separated by arbitrary
204 * strings of whitespace characters (space, tab, newline, return, formfeed).
205 *
206 * If @a to_be_split is empty, then the result will have an empty vector.
207 */
208template <typename Char, typename Traits, typename Alloc>
209std::vector< std::basic_string<Char, Traits, Alloc> >
210split(const std::basic_string<Char, Traits, Alloc>& to_be_split)
211{
212 typedef std::basic_string<Char, Traits, Alloc> string_type;
213 typedef typename string_type::size_type size_type;
214
215 const string_type seperators = impl::whitespace(to_be_split);
216 std::vector< std::basic_string<Char, Traits, Alloc> > result;
217
218 if (to_be_split.empty())
219 {
220 return result;
221 }
222
223 size_type begin = 0;
224 size_type end = to_be_split.find_first_of(seperators);
225 while (end != string_type::npos)
226 {
227 result.push_back(to_be_split.substr(begin, end - begin));
228 begin = to_be_split.find_first_not_of(seperators, end);
229 if (begin == string_type::npos)
230 {
231 result.push_back(string_type());
232 return result;
233 }
234 end = to_be_split.find_first_of(seperators, begin);
235 }
236
237 result.push_back(to_be_split.substr(begin));
238 return result;
239}
240
241
242
243/** @ingroup extended_string
244 * Reflects the Python function @c split without seperator argument
245 *
246 * Return a vector of the words of the string @a to_be_split. The second argument @a seperator
247 * specifies a string to be used as the word separator. The returned vector will then have one
248 * more item than the number of non-overlapping occurrences of the separator in the string.
249 *
250 * The optional third argument @a max_split defaults to 0. If it is nonzero, at most
251 * @a max_split number of splits occur, and the remainder of the string is returned as the final
252 * element of the list (thus, the list will have at most @a max_split + 1 elements).
253 *
254 * If @a to_be_split is empty, then the result will have an empty string as only element.
255 */
256template <typename Char, typename Traits, typename Alloc>
257std::vector< std::basic_string<Char, Traits, Alloc> >
258split(const std::basic_string<Char, Traits, Alloc>& to_be_split,
259 const std::basic_string<Char, Traits, Alloc>& seperator,
260 size_t max_split)
261{
262 typedef std::basic_string<Char, Traits, Alloc> string_type;
263 typedef typename string_type::size_type size_type;
264
265 std::vector< std::basic_string<Char, Traits, Alloc> > result;
266 if (max_split == 0)
267 {
268 max_split = result.max_size() - 1;
269 }
270
271 const size_type seperator_size = seperator.size();
272
273 size_type begin = 0;
274 while (result.size() < max_split)
275 {
276 const size_type end = to_be_split.find(seperator, begin);
277 if (end == string_type::npos)
278 {
279 break;
280 }
281
282 result.push_back(to_be_split.substr(begin, end - begin));
283 begin = end + seperator_size;
284 }
285
286 result.push_back(to_be_split.substr(begin));
287 return result;
288}
289
290/** @ingroup extended_string
291 * Reflects the Python function @c split without seperator argument
292 */
293template <typename Char, typename Traits, typename Alloc>
294std::vector< std::basic_string<Char, Traits, Alloc> >
295split(const std::basic_string<Char, Traits, Alloc>& to_be_split,
296 const Char* seperator,
297 size_t max_split)
298{
299 typedef std::basic_string<Char, Traits, Alloc> string_type;
300 return split(to_be_split, string_type(seperator), max_split);
301}
302
303
304
305/** @ingroup extended_string
306 */
307template <typename Char, typename Traits, typename Alloc, typename InputIterator>
308std::basic_string<Char, Traits, Alloc>
309join(const std::basic_string<Char, Traits, Alloc>& joiner, InputIterator first, InputIterator last)
310{
311 std::basic_ostringstream<Char, Traits, Alloc> buffer;
312 if (first != last)
313 {
314 buffer << *first++;
315 }
316 while (first != last)
317 {
318 buffer << joiner << *first++;
319 }
320 return buffer.str();
321}
322
323
324
325template <typename Char, typename Traits, typename Alloc, typename InputRange> inline
326std::basic_string<Char, Traits, Alloc>
327join_r(const std::basic_string<Char, Traits, Alloc>& joiner, const InputRange& range)
328{
329 return join(joiner, range.begin(), range.end());
330}
331
332
333
334/** @ingroup extended_string
335 * Return a copy of the string @a to_be_stripped with leading characters removed.
336 *
337 * The characters in the string @a to_be_removed will be stripped from the beginning of the string
338 * @a to_be_stripped.
339 */
340template <typename Char, typename Traits, typename Alloc>
341std::basic_string<Char, Traits, Alloc>
342lstrip(const std::basic_string<Char, Traits, Alloc>& to_be_stripped,
343 const std::basic_string<Char, Traits, Alloc>& to_be_removed)
344{
345 typedef std::basic_string<Char, Traits, Alloc> string_type;
346 const typename string_type::size_type begin = to_be_stripped.find_first_not_of(to_be_removed);
347 return begin == string_type::npos ? string_type() : to_be_stripped.substr(begin);
348}
349
350
351
352/** @ingroup extended_string
353 * Return a copy of the string @a to_be_stripped with leading whitespace removed.
354 */
355template <typename Char, typename Traits, typename Alloc> inline
356std::basic_string<Char, Traits, Alloc>
357lstrip(const std::basic_string<Char, Traits, Alloc>& to_be_stripped)
358{
359 return lstrip(to_be_stripped, impl::whitespace(to_be_stripped));
360}
361
362
363
364/** @ingroup extended_string
365 * Return a copy of the string @a to_be_stripped with trailing characters removed.
366 *
367 * The characters in the string @a to_be_removed will be stripped from the ending of the string
368 * @a to_be_stripped.
369 */
370template <typename Char, typename Traits, typename Alloc>
371std::basic_string<Char, Traits, Alloc>
372rstrip(const std::basic_string<Char, Traits, Alloc>& to_be_stripped,
373 const std::basic_string<Char, Traits, Alloc>& to_be_removed)
374{
375 typedef std::basic_string<Char, Traits, Alloc> string_type;
376 const typename string_type::size_type end = to_be_stripped.find_last_not_of(to_be_removed);
377 return end == string_type::npos ? string_type() : to_be_stripped.substr(0, end + 1);
378}
379
380
381
382/** @ingroup extended_string
383 * Return a copy of the string @a to_be_stripped with trailing whitespace removed.
384 */
385template <typename Char, typename Traits, typename Alloc> inline
386std::basic_string<Char, Traits, Alloc>
387rstrip(const std::basic_string<Char, Traits, Alloc>& to_be_stripped)
388{
389 return rstrip(to_be_stripped, impl::whitespace(to_be_stripped));
390}
391
392
393
394/** @ingroup extended_string
395 * Return a copy of the string @a to_be_stripped with both leading and trailing characters removed.
396 *
397 * The characters in the string @a to_be_removed will be stripped from both the beginning and the
398 * ending of the string @a to_be_stripped.
399 */
400template <typename Char, typename Traits, typename Alloc>
401std::basic_string<Char, Traits, Alloc>
402strip(const std::basic_string<Char, Traits, Alloc>& to_be_stripped,
403 const std::basic_string<Char, Traits, Alloc>& to_be_removed)
404{
405 typedef std::basic_string<Char, Traits, Alloc> string_type;
406 const typename string_type::size_type begin = to_be_stripped.find_first_not_of(to_be_removed);
407 const typename string_type::size_type end = to_be_stripped.find_last_not_of(to_be_removed);
408 return begin == string_type::npos ? string_type() : to_be_stripped.substr(begin, end - begin + 1);
409}
410
411
412
413/** @ingroup extended_string
414 * Return a copy of the string @a to_be_stripped with leading and trailing whitespace removed.
415 */
416template <typename Char, typename Traits, typename Alloc> inline
417std::basic_string<Char, Traits, Alloc>
418strip(const std::basic_string<Char, Traits, Alloc>& to_be_stripped)
419{
420 return strip(to_be_stripped, impl::whitespace(to_be_stripped));
421}
422
423
424
425}
426
427}
428
429// EOF
size_type size() const
returns the N, the number of elements in the list.
Definition slist.inl:411
std::basic_string< Char, Traits, Alloc > lstrip(const std::basic_string< Char, Traits, Alloc > &to_be_stripped, const std::basic_string< Char, Traits, Alloc > &to_be_removed)
Return a copy of the string to_be_stripped with leading characters removed.
bool begins_with(const std::basic_string< Char, Traits, Alloc > &input, const std::basic_string< Char, Traits, Alloc > &prefix)
returns true if input begins with the input prefix
std::basic_string< Char, Traits, Alloc > rstrip(const std::basic_string< Char, Traits, Alloc > &to_be_stripped, const std::basic_string< Char, Traits, Alloc > &to_be_removed)
Return a copy of the string to_be_stripped with trailing characters removed.
std::basic_string< Char, Traits, Alloc > replace_all(const std::basic_string< Char, Traits, Alloc > &input, const std::basic_string< Char, Traits, Alloc > &to_be_replaced, const std::basic_string< Char, Traits, Alloc > &replacement)
replace all instances of to_be_replaced in input by replacement.
std::basic_string< Char, Traits, Alloc > tolower(const std::basic_string< Char, Traits, Alloc > &input, const std::locale &locale=std::locale())
convert std::basic_string to lower case by using user locale
std::vector< std::basic_string< Char, Traits, Alloc > > split(const std::basic_string< Char, Traits, Alloc > &to_be_split)
Reflects the Python function split without seperator argument.
std::basic_string< Char, Traits, Alloc > toupper(const std::basic_string< Char, Traits, Alloc > &input, const std::locale &locale=std::locale())
convert std::basic_string to upper case by using user locale
bool ends_with(const std::basic_string< Char, Traits, Alloc > &input, const std::basic_string< Char, Traits, Alloc > &suffix)
returns true if input ends with the input suffix
std::basic_string< Char, Traits, Alloc > strip(const std::basic_string< Char, Traits, Alloc > &to_be_stripped, const std::basic_string< Char, Traits, Alloc > &to_be_removed)
Return a copy of the string to_be_stripped with both leading and trailing characters removed.
lass extensions to the standard library
Library for Assembled Shared Sources.
Definition config.h:53