9
template <class T, class CharT = char, class SizeT = std::string::size_type, class Dist = ptrdiff_t>
10
class basic_split_iterator : public std::iterator<std::input_iterator_tag, T, Dist, const T*, const T&> {
12
basic_split_iterator() : str(""), separator('\0') {
14
nextpos = std::string::npos;
17
basic_split_iterator(T& s, CharT ch) : str(s), separator(ch) {
19
nextpos = str.find_first_of(separator);
23
if (nextpos == std::string::npos)
24
return str.substr(pos);
26
return str.substr(pos, nextpos - pos);
29
const T& operator*() const {
32
const T* operator->() const {
33
return &(operator*());
36
basic_split_iterator& operator++() {
37
if (nextpos == std::string::npos) pos = 0;
40
nextpos = str.find_first_of(separator, pos + 1);
45
bool operator==(const basic_split_iterator& i) const {
46
return ((nextpos==i.nextpos)&&(pos==i.pos));
49
bool operator!=(const basic_split_iterator& i) const {
50
// std::cout << nextpos << "=" << i.nextpos << "," << pos << "=" << i.pos << std::endl;
51
return ((nextpos!=i.nextpos)||(pos!=i.pos));
56
const CharT separator;
61
template < class Ch = char, class Tr = std::char_traits<Ch>, class A = std::allocator<Ch> >
62
class basic_csv_string : public std::basic_string<Ch,Tr,A> {
64
typedef basic_csv_string<Ch, Tr, A> Self;
65
typedef std::vector<Self> SelfVector;
66
typedef std::basic_string<Ch, Tr, A> Base;
69
typedef typename std::basic_string<Ch, Tr, A>::size_type size_type;
72
/* actually, we need to define all constructors */
73
basic_csv_string() : std::basic_string<Ch,Tr,A>() { }
74
basic_csv_string(const char *ch) : std::basic_string<Ch,Tr,A>(ch) { }
75
basic_csv_string(std::basic_string<Ch, Tr, A> str) : std::basic_string<Ch,Tr,A>(str) { }
77
template<class InputIterator>
78
basic_csv_string(InputIterator __beg, InputIterator __end) : std::basic_string<Ch,Tr,A>(__beg, __end) { }
81
Self substr(size_type start = 0, size_type leng = 0) const;
84
std::vector<ResT> *split(std::vector<ResT> &result, Ch c);
86
basic_split_iterator<Self, Ch> create_split_iterator(Ch c);
90
typedef class basic_csv_string<char> csv_string;
91
typedef class basic_split_iterator<csv_string> split_iterator;
97
template <class Ch, class Tr, class A>
98
basic_csv_string<Ch,Tr,A> basic_csv_string<Ch,Tr,A>::substr(size_type start, size_type leng) const {
99
std::string::size_type len = leng?(leng):(Base::length() - start);
101
while ((len>0)&&((at(start) == ' ')||(at(start) == '\t'))) {
105
while ((len>0)&&((at(start+len-1)==' ')||(at(start+len-1)=='\r')||(at(start+len-1)=='\n')||(at(start+len-1)=='\t'))) len--;
107
return basic_string<Ch,Tr,A>::substr(start,len);
110
template <class Ch, class Tr, class A> template <class ResT>
111
vector<ResT> *basic_csv_string<Ch,Tr,A>::split(vector<ResT> &result, Ch c) {
112
csv_string::size_type pos, nextpos = basic_csv_string<Ch,Tr,A>::find_first_of(c);
113
for (pos = 0; nextpos != string::npos; nextpos = basic_csv_string<Ch,Tr,A>::find_first_of(c, pos + 1)) {
114
csv_string word = substr(pos, nextpos - pos);
115
/* if (word.length()>0)*/ result.push_back(word);
118
csv_string word = substr(pos);
119
/* if (word.length()>0)*/ result.push_back(word);
124
template <class Ch, class Tr, class A>
125
basic_split_iterator<basic_csv_string<Ch, Tr, A>, Ch> basic_csv_string<Ch,Tr,A>::create_split_iterator(Ch c) {
126
return basic_split_iterator<basic_csv_string<Ch, Tr, A>, Ch, typename basic_csv_string<Ch, Tr, A>::size_type>(*this, c);
129
#endif /* _DS_STRING_H */