4 #include <msp/core/algorithm.h>
11 template<bool long_sep, bool allow_empty>
12 vector<string> do_split(const string &str, const string &sep, int max_split)
14 vector<string> result;
17 while(start<str.size())
19 unsigned end = long_sep ? str.find(sep, start) : str.find_first_of(sep, start);
20 if(end!=start || allow_empty)
22 if(max_split>=0 && result.size()==static_cast<unsigned>(max_split))
24 result.push_back(str.substr(start));
28 result.push_back(str.substr(start, end-start));
34 start = end+(long_sep ? sep.size() : 1);
36 if(allow_empty && start==str.size())
37 result.push_back(string());
48 int strcasecmp(const string &s1, const string &s2)
52 for(; (i1!=s1.end() && i2!=s2.end()); ++i1, ++i2)
54 const char c1 = ::tolower(*i1);
55 const char c2 = ::tolower(*i2);
56 if(c1!=c2) return c1-c2;
58 if(i1!=s1.end()) return *i1;
59 if(i2!=s2.end()) return -*i2;
63 string tolower(const string &str)
66 transform(result, [](char c){ return std::tolower(c); });
70 string toupper(const string &str)
73 transform(result, [](char c){ return std::toupper(c); });
77 bool isnumrc(const string &str)
79 return all_of(str.begin(), str.end(), [](char c){ return std::isdigit(c); });
82 bool isalpha(const string &str)
84 return all_of(str.begin(), str.end(), [](char c){ return std::isalpha(c); });
87 bool isalnum(const string &str)
89 return all_of(str.begin(), str.end(), [](char c){ return std::isalnum(c); });
92 vector<string> split(const string &str, const string &sep, int max_split)
94 return do_split<false, false>(str, sep, max_split);
97 vector<string> split(const string &str, char sep, int max_split)
99 return split(str, string(1, sep), max_split);
102 vector<string> split_long(const string &str, const string &sep, int max_split)
104 return do_split<true, false>(str, sep, max_split);
107 vector<string> split_fields(const string &str, const string &sep, int max_split)
109 return do_split<true, true>(str, sep, max_split);
112 vector<string> split_fields(const string &str, char sep, int max_split)
114 return split_fields(str, string(1, sep), max_split);
117 string strip(const string &s)
120 if(!result.erase(0, result.find_first_not_of(" \t\r\n")).empty())
121 result.erase(result.find_last_not_of(" \t\r\n")+1);
125 string &append(string &str, const string &sep, const string &other)
127 if(!str.empty() && !other.empty())
133 string join(const string &str1, const string &sep, const string &str2)
135 string result = str1;
136 return append(result, sep, str2);
139 string c_unescape(const string &str)
142 unsigned numeric_type = 0;
143 unsigned numeric_pos = 0;
144 unsigned numeric_value = 0;
153 else if(c>='a' && c<='f')
155 else if(c>='A' && c<='F')
158 throw invalid_argument("c_unescape");
160 numeric_value = (numeric_value<<4 | digit);
164 result += numeric_value;
168 else if(numeric_type==8)
174 throw invalid_argument("c_unescape");
176 numeric_value = (numeric_value<<3 | digit);
180 result += numeric_value;
192 else if(c>='0' && c<='3')
196 numeric_value = c-'0';
219 throw invalid_argument("c_unescape");
230 throw invalid_argument("c_unescape");
235 string c_escape(const string &str, bool escape_8bit)
261 else if(static_cast<unsigned char>(c)<' ' || (escape_8bit && (c&0x80)))
263 char buf[4] = { '\\', 0 };
264 for(unsigned j=0; j<3; ++j)
265 buf[1+j] = '0'+((static_cast<unsigned char>(c)>>(6-j*3))&7);
266 result.append(buf, 4);