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());
43 bool check_str(const std::string &str, int (*pred)(int))
45 for(string::const_iterator i=str.begin(); i!=str.end(); ++i)
56 int strcasecmp(const string &s1, const string &s2)
58 string::const_iterator i1 = s1.begin();
59 string::const_iterator i2 = s2.begin();
60 for(; (i1!=s1.end() && i2!=s2.end()); ++i1, ++i2)
62 const char c1 = ::tolower(*i1);
63 const char c2 = ::tolower(*i2);
64 if(c1!=c2) return c1-c2;
66 if(i1!=s1.end()) return *i1;
67 if(i2!=s2.end()) return -*i2;
71 string tolower(const string &str)
74 transform(result.begin(), result.end(), result.begin(), ::tolower);
78 string toupper(const string &str)
81 transform(result.begin(), result.end(), result.begin(), ::toupper);
85 bool isnumrc(const string &str)
87 return check_str(str, isdigit);
90 bool isalpha(const string &str)
92 return check_str(str, isalpha);
95 bool isalnum(const string &str)
97 return check_str(str, isalnum);
100 vector<string> split(const string &str, const string &sep, int max_split)
102 return do_split<false, false>(str, sep, max_split);
105 vector<string> split(const string &str, char sep, int max_split)
107 return split(str, string(1, sep), max_split);
110 vector<string> split_long(const string &str, const string &sep, int max_split)
112 return do_split<true, false>(str, sep, max_split);
115 vector<string> split_fields(const string &str, const string &sep, int max_split)
117 return do_split<true, true>(str, sep, max_split);
120 vector<string> split_fields(const string &str, char sep, int max_split)
122 return split_fields(str, string(1, sep), max_split);
125 string strip(const string &s)
128 if(!result.erase(0, result.find_first_not_of(" \t\r\n")).empty())
129 result.erase(result.find_last_not_of(" \t\r\n")+1);
133 string &append(string &str, const string &sep, const string &other)
135 if(!str.empty() && !other.empty())
141 string join(const string &str1, const string &sep, const string &str2)
143 string result = str1;
144 return append(result, sep, str2);
147 string c_unescape(const std::string &str)
150 unsigned numeric_type = 0;
151 unsigned numeric_pos = 0;
152 unsigned numeric_value = 0;
154 for(string::const_iterator i=str.begin(); i!=str.end(); ++i)
159 if(*i>='0' && *i<='9')
161 else if(*i>='a' && *i<='f')
163 else if(*i>='A' && *i<='F')
166 throw invalid_argument("c_unescape");
168 numeric_value = (numeric_value<<4 | digit);
172 result += numeric_value;
176 else if(numeric_type==8)
179 if(*i>='0' && *i<='7')
182 throw invalid_argument("c_unescape");
184 numeric_value = (numeric_value<<3 | digit);
188 result += numeric_value;
200 else if(*i>='0' && *i<='3')
204 numeric_value = *i-'0';
227 throw invalid_argument("c_unescape");
238 throw invalid_argument("c_unescape");
243 string c_escape(const string &str, bool escape_8bit)
247 for(string::const_iterator i=str.begin(); i!=str.end(); ++i)
269 else if(static_cast<unsigned char>(*i)<' ' || (escape_8bit && (*i&0x80)))
271 char buf[4] = { '\\', 0 };
272 for(unsigned j=0; j<3; ++j)
273 buf[1+j] = '0'+((static_cast<unsigned char>(*i)>>(6-j*3))&7);
274 result.append(buf, 4);