2 #ifndef WIBBLE_STRING_H
3 #define WIBBLE_STRING_H
44 using namespace wibble::operators;
47 static int vasprintf (
char **,
const char *, va_list);
50 std::string
fmtf(
const char* f, ... );
51 template<
typename T >
inline std::string
fmt(
const T& val);
55 template<
typename X >
57 std::ostream &o, X list )
63 while( !list.empty() ) {
64 o <<
fmt( list.head() );
65 if ( !list.tail().empty() )
73 template<
typename T >
74 inline std::string
fmt(
const T& val)
76 std::stringstream str;
81 template<>
inline std::string fmt<std::string>(
const std::string& val) {
84 template<>
inline std::string
fmt<char*>(
char *
const & val) {
return val; }
86 template<
typename C >
95 for (
typename C::const_iterator i = c.begin(); i != c.end(); ++i ) {
97 if ( i != c.end() && i + 1 != c.end() )
106 template<
typename X >
107 inline std::string
fmt(
const std::set< X >& val) {
112 template<
typename X >
113 inline std::string
fmt(
const std::vector< X > &val) {
118 template<
typename X >
119 inline std::string
fmt(
const std::deque< X > &val) {
124 inline std::string
basename(
const std::string& pathname)
126 size_t pos = pathname.rfind(
"/");
127 if (pos == std::string::npos)
130 return pathname.substr(pos+1);
134 inline std::string
dirname(
const std::string& pathname)
136 size_t pos = pathname.rfind(
"/");
137 if (pos == std::string::npos)
138 return std::string();
141 return std::string(
"/");
143 return pathname.substr(0, pos);
151 std::string
normpath(
const std::string& pathname);
154 inline bool startsWith(
const std::string& str,
const std::string& part)
156 if (str.size() < part.size())
158 return str.substr(0, part.size()) == part;
162 inline bool endsWith(
const std::string& str,
const std::string& part)
164 if (str.size() < part.size())
166 return str.substr(str.size() - part.size()) == part;
169 inline std::string
replace(
const std::string& str,
char from,
char to)
172 res.reserve(str.size());
173 for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
181 #if !__xlC__ && (! __GNUC__ || __GNUC__ >= 4)
186 template<
typename FUN>
187 inline std::string
trim(
const std::string& str,
const FUN& classifier)
193 size_t end = str.size() - 1;
194 while (beg < end && classifier(str[beg]))
196 while (end >= beg && classifier(str[end]))
199 return str.substr(beg, end-beg+1);
205 inline std::string
trim(
const std::string& str)
207 return trim(str, ::isspace);
210 inline std::string
trim(
const std::string& str)
217 size_t end = str.size() - 1;
218 while (beg < end && ::isspace(str[beg]))
220 while (end >= beg && ::isspace(str[end]))
223 return str.substr(beg, end-beg+1);
228 inline std::string
toupper(
const std::string& str)
231 res.reserve(str.size());
232 for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
238 inline std::string
tolower(
const std::string& str)
241 res.reserve(str.size());
242 for (std::string::const_iterator i = str.begin(); i != str.end(); ++i)
248 inline std::string
ucfirst(
const std::string& str)
250 if (str.empty())
return str;
253 return res +
tolower(str.substr(1));
257 inline std::string
joinpath(
const std::string& path1,
const std::string& path2)
264 if (path1[path1.size() - 1] ==
'/')
266 return path1 + path2.substr(1);
268 return path1 + path2;
271 return path1 + path2;
273 return path1 +
'/' + path2;
277 inline std::string
appendpath(
const std::string &path1,
const std::string &path2 ) {
279 if ( path2.size() >= 1 && path2[ 0 ] ==
'/' )
283 if ( ( path2.size() >= 3 && path2[ 1 ] ==
':' && path2[ 2 ] ==
'\\' )
284 || ( path2.size() >= 2 && path2[ 0 ] ==
'\\' && path2[ 1 ] ==
'\\' ) )
291 std::string
urlencode(
const std::string& str);
294 std::string
urldecode(
const std::string& str);
323 const std::string& sep;
324 const std::string& str;
329 const_iterator(
const std::string& sep,
const std::string& str) : sep(sep), str(str), pos(0)
333 const_iterator(
const std::string& sep,
const std::string& str,
bool) : sep(sep), str(str), pos(std::string::npos) {}
337 if (pos == str.size())
338 pos = std::string::npos;
343 if (pos + 1 == str.size())
344 end = std::string::npos;
348 end = str.find(sep, pos);
349 if (end == std::string::npos)
351 cur = str.substr(pos);
356 cur = str.substr(pos, end-pos);
357 pos = end + sep.size();
365 if (pos == std::string::npos)
366 return std::string();
368 return str.substr(pos);
383 return pos == ti.pos;
389 return pos != ti.pos;
396 Split(
const std::string& sep,
const std::string& str) : sep(sep), str(str) {}
405 template<
typename ITER>
406 std::string
join(
const ITER&
begin,
const ITER& end,
const std::string& sep =
", ")
408 std::stringstream res;
410 for (ITER i = begin; i !=
end; ++i)
442 std::pair<std::string, std::string> value;
451 const std::pair<std::string, std::string>&
operator*()
const
455 const std::pair<std::string, std::string>*
operator->()
const
476 std::string
c_escape(
const std::string& str);
485 std::string
c_unescape(
const std::string& str,
size_t& lenParsed);