Add string join and split functions

pull/2/head
Stelios Bounanos 2009-06-30 16:26:07 +01:00
rodzic d70ea69254
commit 8283833124
3 zmienionych plików z 162 dodań i 0 usunięć

Wyświetl plik

@ -358,6 +358,7 @@ fldigi_SOURCES += \
include/spot.h \
include/stacktrace.h \
include/status.h \
include/strutil.h \
include/testmodem.h \
include/threads.h \
include/throb.h \
@ -424,6 +425,7 @@ fldigi_SOURCES += \
misc/socket.cxx \
misc/stacktrace.cxx \
misc/status.cxx \
misc/strutil.cxx \
misc/threads.cxx \
misc/timeops.cxx \
misc/util.cxx \

Wyświetl plik

@ -0,0 +1,119 @@
#ifndef STRUTIL_H_
#define STRUTIL_H_
#include <ostream>
#include <iterator>
#include <sstream>
#include <algorithm>
#include <string>
namespace join_ {
template <typename T> struct empty {
bool operator()(const T& v) const { return false; };
};
template <> struct empty<const char*> {
bool operator()(const char* v) const { return !v || *v == '\0'; };
};
template <> struct empty<char*> {
bool operator()(char* v) const { return !v || *v == '\0'; };
};
template <> struct empty<const wchar_t*> {
bool operator()(const wchar_t* v) const { return !v || *v == L'\0'; };
};
template <> struct empty<wchar_t*> {
bool operator()(wchar_t* v) const { return !v || *v == L'\0'; };
};
template <typename C> struct empty<std::basic_string<C> > {
bool operator()(const std::basic_string<C>& v) const { return v.empty(); };
};
template <typename T, typename CharT = char, typename TraitsT = std::char_traits<CharT> >
class ostream_iterator
: public std::iterator<std::output_iterator_tag, void, void, void, void>
{
public:
typedef std::basic_ostream<CharT, TraitsT> ostream_type;
ostream_iterator(ostream_type& s, const CharT* sep = 0, bool ie = false)
: stream(&s), join_string(sep), print_sep(false), ignore_empty(ie) { }
ostream_iterator& operator=(const T& value)
{
if (!ignore_empty || !is_empty(value)) {
if (print_sep)
*stream << join_string;
*stream << value;
print_sep = true;
}
return *this;
}
ostream_iterator& operator*(void) { return *this; }
ostream_iterator& operator++(void) { return *this; }
ostream_iterator& operator++(int) { return *this; }
private:
ostream_type* stream;
const CharT* join_string;
bool print_sep, ignore_empty;
empty<T> is_empty;
};
};
template <typename T, typename CharT, typename TraitsT>
std::basic_ostream<CharT, TraitsT>&
join(std::basic_ostream<CharT, TraitsT>& stream,
const T* begin, const T* end, const char* sep, bool ignore_empty = false)
{
std::copy(begin, end, join_::ostream_iterator<T, CharT, TraitsT>(stream, sep, ignore_empty));
return stream;
}
template <typename T, typename CharT, typename TraitsT>
std::basic_ostream<CharT, TraitsT>&
join(std::basic_ostream<CharT, TraitsT>& stream,
const T* ptr, size_t len, const char* sep, bool ignore_empty = false)
{
join<T, CharT, TraitsT>(stream, ptr, ptr + len, sep, ignore_empty);
return stream;
}
template <typename T>
std::string join(const T* begin, const T* end, const char* sep, bool ignore_empty = false)
{
std::ostringstream stream;
join<T>(stream, begin, end, sep, ignore_empty);
return stream.str();
}
template <typename T>
std::string join(const T* ptr, size_t len, const char* sep, bool ignore_empty = false)
{
return join<T>(ptr, ptr + len, sep, ignore_empty);
}
template <typename CharT>
std::basic_string<CharT> join(const std::basic_string<CharT>* begin, const std::basic_string<CharT>* end,
const char* sep, bool ignore_empty = false)
{
std::basic_ostringstream<CharT, std::char_traits<CharT> > stream;
join<std::basic_string<CharT> >(stream, begin, end, sep, ignore_empty);
return stream.str();
}
template <typename CharT>
std::basic_string<CharT> join(const std::basic_string<CharT>* begin, size_t len,
const char* sep, bool ignore_empty = false)
{
return join<CharT>(begin, begin + len, sep, ignore_empty);
}
#include <vector>
#include <climits>
std::vector<std::string> split(const char* re_str, const char* str, unsigned max_split = UINT_MAX);
#endif // STRUTIL_H_
// Local Variables:
// mode: c++
// c-file-style: "linux"
// End:

Wyświetl plik

@ -0,0 +1,41 @@
#include <config.h>
#include <vector>
#include <string>
#include <cstring>
#include <climits>
#include "re.h"
#include "strutil.h"
using namespace std;
vector<string> split(const char* re_str, const char* str, unsigned max_split)
{
vector<string> v;
size_t n = strlen(re_str);
string s; s.reserve(n + 2); s.append(1, '(').append(re_str, n).append(1, ')');
fre_t re(s.c_str(), REG_EXTENDED);
bool ignore_trailing_empty = false;
if (max_split == 0) {
max_split = UINT_MAX;
ignore_trailing_empty = true;
}
s = str;
const vector<regmatch_t>& sub = re.suboff();
while (re.match(s.c_str())) {
if (unlikely(sub.empty() || ((max_split != UINT_MAX) && --max_split == 0)))
break;
else {
s[sub[0].rm_so] = '\0';
v.push_back(s.c_str());
s.erase(0, sub[0].rm_eo);
}
}
if (!(ignore_trailing_empty && s.empty()))
v.push_back(s);
return v;
}