]> git.tdb.fi Git - libs/core.git/blob - source/utils.cpp
Add utils
[libs/core.git] / source / utils.cpp
1 #include <list>
2 #include "utils.h"
3
4 using namespace std;
5
6 namespace Msp {
7
8 /**
9 Compares two strings, ignoring case.
10
11 @param   s1  First string
12 @param   s2  Second string
13
14 @return  -1 if s1<s2, 0 if s1==s2, 1 if s1>s2
15 */
16 int strcasecmp(const string &s1, const string &s2)
17 {
18         string::const_iterator i1=s1.begin();
19         string::const_iterator i2=s2.begin();
20         for(; (i1!=s1.end() && i2!=s2.end()); ++i1, ++i2)
21         {
22                 const char c1=::tolower(*i1);
23                 const char c2=::tolower(*i2);
24                 if(c1!=c2) return c1-c2;
25         }
26         if(i1!=s1.end()) return *i1;
27         if(i2!=s2.end()) return -*i2;
28         return 0;
29 }
30
31 /**
32 Returns a lowercase copy of the given string.
33 */
34 string tolower(const string &str)
35 {
36         string  result(str);
37         transform(result.begin(), result.end(), result.begin(), ::tolower);
38         return result;
39 }
40
41 /**
42 Returns an uppercase copy of the given string.
43 */
44 string toupper(const string &str)
45 {
46         string  result(str);
47         transform(result.begin(), result.end(), result.begin(), ::toupper);
48         return result;
49 }
50
51 /**
52 Splits a string to parts.
53
54 @param   str          String to be split
55 @param   sep          A set of separator characters
56 @param   allow_empty  Whether or not to produce empty parts for sequences of
57                       more than one separator character
58 */
59 vector<string> split(const string &str, const string &sep, bool allow_empty)
60 {
61         vector<string> result;
62         unsigned start=str.find_first_not_of(sep);
63         while(start<str.size())
64         {
65                 unsigned        end=str.find_first_of(sep, start);
66                 result.push_back(str.substr(start, end-start));
67                 if(end==string::npos) break;
68                 if(allow_empty)
69                         start=end+1;
70                 else
71                         start=str.find_first_not_of(sep, end);
72         }
73         return result;
74 }
75
76 vector<string> split(const string &str, char sep, bool allow_empty)
77 {
78         return split(str, string(1,sep), allow_empty);
79 }
80
81 /**
82 Builds a single string from the strings in the given sequence by concatenating
83 them.
84
85 @param  seq  A sequence of strings
86 @param  sep  Separator to be inserted between strings
87 */
88 template<typename T>
89 string join(const T &seq, const string &sep)
90 {
91         string result;
92         for(typename T::const_iterator i=seq.begin(); i!=seq.end(); ++i)
93         {
94                 if(i!=seq.begin())
95                         result+=sep;
96                 result+=*i;
97         }
98
99         return result;
100 }
101 template string join<list<string> >(const list<string> &, const string &);
102 template string join<vector<string> >(const vector<string> &, const string &);
103
104 /**
105 Returns a copy of the given string with leading and trailing whitespace
106 removed.
107 */
108 string strip(const string &s)
109 {
110         string result=s;
111         if(!result.erase(0, result.find_first_not_of(" \t\n")).empty())
112                 result.erase(result.find_last_not_of(" \t\n")+1);
113         return result;
114 }
115
116 } // namespace Msp