38#ifndef DRAIN_STRING_TOOLS
39#define DRAIN_STRING_TOOLS
60 bool startsWith(
const std::string &s,
const std::string & substring);
64 bool endsWith(
const std::string &s,
const std::string & substring);
71 std::string &
upperCase(std::string & s,
size_t n = std::numeric_limits<size_t>::max());
84 std::string &
lowerCase(std::string & s,
size_t n = std::numeric_limits<size_t>::max());
99 void replace(
const std::string &src,
char search,
char repl, std::ostream & ostr);
106 void replace(
const std::string &src,
char from,
char repl, std::string &dst);
112 template <
typename S,
typename R>
114 void replace(
const std::string &src,
const S & search,
const R & repl, std::ostream & ostr){
116 const size_t length = getLength(search);
117 std::string::size_type i = 0;
118 std::string::size_type pos;
121 pos = src.find(search, i);
122 if (pos == std::string::npos){
123 ostr << src.substr(i);
128 ostr << src.substr(i, pos-i) << repl;
140 template <
typename T1,
typename T2>
142 void replace(
const std::string &src,
const T1 &search,
const T2 & repl, std::string & dst){
143 std::stringstream result;
144 replace(src, search, repl, result);
169 template <
typename T>
171 void replace(
const std::string & src,
const std::map<char,T> & m, std::ostream & ostr){
172 typename std::map<char,T>::const_iterator it;
184 template <
typename T>
186 void replace(
const std::string & src,
const std::map<char,T> & m, std::string & dst){
187 std::stringstream result;
197 void replace(
const std::string & src,
const std::map<char,char> & m, std::string & dst);
204 template <
class K,
class V>
206 void replace(
const std::string & src,
const std::map<K,V> & m, std::string & dst){
207 replaceWithMap(src, m, dst);
210 template <
class K,
class V>
212 void replace(
const std::string & src,
const std::initializer_list<std::pair<K,V> > & m, std::string & dst){
213 replaceWithMap(src, m, dst);
232 void getSafeKey(
const std::string & src, std::string & dst,
const std::string & accept=
"_",
const std::string & toUnderScore=
"");
237 size_t getLength(
char c){
242 size_t getLength(
const std::string & s){
248 void replaceWithMap(
const std::string & src,
const M & m, std::string & dst){
258 for (
const auto & entry: m){
260 replace(dst, entry.first, entry.second, dst);
271 std::string
trim(
const std::string &s,
const std::string &trimChars=
" \t\n\r");
282 std::string
trimSymmetric(
const std::string &s,
const std::string &leading=
"'\"",
const std::string & trailing=
"");
298 bool trimScan(
const std::string &s, std::size_t & pos1, std::size_t & pos2,
const std::string &trimChars=
" \t\n");
318 template <
class T,
class C>
320 void split(
const std::string & s, T & sequence,
const C &separators,
const std::string & trimChars=
" \t\n");
348 template <
class T1,
class T2,
class C>
350 bool split2(
const std::string & s, T1 & first, T2 & second,
const C &separators,
const std::string & trimChars=
" \t\n");
360 size_t extractPrefixLength(
const std::string & src1,
const std::string & src2,
size_t step = 1);
372 size_t extractPrefix(
const std::string & src1,
const std::string & src2,
373 std::string & prefix, std::string & dst1, std::string & dst2,
size_t step = 1);
383 size_t extractPrefix(std::string & s1, std::string & s2, std::string & prefix,
size_t step = 1){
394 std::ostream &
join(
const T & container, std::ostream & ostr,
char separator = 0){
396 for (
typename T::const_iterator it = container.begin(); it != container.end(); ++it){
411 std::string
join(T & container,
char separator = 0){
412 std::stringstream sstr;
418 template <
unsigned int S>
420 void read(std::istream &istr, std::string & s){
422 while (istr.read(buffer, S)){
425 s.append(buffer, istr.gcount());
440 void convert(
const std::string &s, T & dst);
451 T
convert(
const std::string &s);
456 std::string &
import(
const T & src, std::string & target);
476 const T &
lazyConvert(
const std::string &s, T & tmp);
482 void appendString(T & sequence,
const std::string & str){
483 typename T::value_type tmp;
487 template <
class T,
size_t N>
491 appendString(l, str);
501 void appendSubstring(T & sequence,
const std::string & str, std::string::size_type pos, std::string::size_type n){
504 appendString(sequence, str.substr(pos, n));
507 appendString(sequence,
"");
515template <
class T,
class C>
516void StringTools::split(
const std::string & str, T & sequence,
const C & separators,
const std::string & trimChars){
520 const bool TRIM = !trimChars.empty();
521 const std::string::size_type n = str.size();
523 std::string::size_type pos1 = 0;
524 std::string::size_type pos2 = n;
533 appendSubstring(sequence, str, pos1, pos2-pos1);
536 appendString(sequence, str);
543 std::string::size_type pos = pos1;
548 pos = str.find_first_of(separators, pos);
549 if (pos == std::string::npos){
554 appendSubstring(sequence, str, pos1, pos2-pos1);
562 appendSubstring(sequence, str, pos1, pos2-pos1);
563 pos = str.find_first_not_of(trimChars, pos+1);
577template <
class T1,
class T2,
class S>
578bool StringTools::split2(
const std::string & s, T1 & first, T2 & second,
const S & separators,
const std::string & trimChars){
580 std::size_t i = s.find_first_of(separators);
582 if (i != std::string::npos){
584 std::string srcFirst(s, 0, i);
586 std::string srcSecond(s, std::min(s.size(), i));
588 if (!trimChars.empty()){
595 if (!srcSecond.empty()){
596 if (!trimChars.empty()){
624 if (trimChars.empty()){
656 std::stringstream sstr(str);
681std::string & StringTools::import(
const std::string & src, std::string & dst){
687std::string & StringTools::import(
const T & x, std::string & dst){
688 std::stringstream sstr;
690 dst.assign(sstr.str());
tuplebase_t & assignSequence(T &sequence, bool LENIENT=false)
Proposed for tuples only; derived classes should not shadow this.
Definition TupleBase.h:287
Tuple of N elements of type T.
Definition UniTuple.h:65