/adei/trunk

To get this branch, use:
bzr branch http://darksoft.org/webbzr/adei/trunk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#ifndef _DS_STRING_H
#define _DS_STRING_H

#include <string>
#include <vector>
#include <iterator>

namespace ds {
 template <class T, class CharT = char, class SizeT = std::string::size_type, class Dist = ptrdiff_t> 
 class basic_split_iterator : public std::iterator<std::input_iterator_tag, T, Dist, const T*, const T&> {
  public:
    basic_split_iterator() : str(""), separator('\0') {
	pos = 0;
	nextpos = std::string::npos;
    }

    basic_split_iterator(T& s, CharT ch) : str(s), separator(ch) {
	pos = 0;
	nextpos = str.find_first_of(separator);
    }
    
    T operator*() const {
	if (nextpos == std::string::npos)
	    return str.substr(pos);
	else 
	    return str.substr(pos, nextpos - pos);
    }
/*    
    const T& operator*() const {
    }
    
    const T* operator->() const {
	return &(operator*());
    }
*/    
    basic_split_iterator& operator++() {
	if (nextpos == std::string::npos) pos = 0;
	else {
	    pos = nextpos + 1;
	    nextpos = str.find_first_of(separator, pos + 1);
	}
	return *this;
    }
    
    bool operator==(const basic_split_iterator& i) const {
	return ((nextpos==i.nextpos)&&(pos==i.pos));
    }

    bool operator!=(const basic_split_iterator& i) const {
//	std::cout << nextpos << "=" << i.nextpos << "," << pos << "=" << i.pos << std::endl;
	return ((nextpos!=i.nextpos)||(pos!=i.pos));
    }

  private:
    const T& str;
    const CharT separator;
    SizeT pos;
    SizeT nextpos;
 };

 template < class Ch = char, class Tr = std::char_traits<Ch>, class A = std::allocator<Ch> >
 class basic_csv_string : public std::basic_string<Ch,Tr,A> {
  protected:
    typedef basic_csv_string<Ch, Tr, A> Self;
    typedef std::vector<Self> SelfVector;
    typedef std::basic_string<Ch, Tr, A> Base;

  public:
    typedef typename std::basic_string<Ch, Tr, A>::size_type size_type;

  public:
	/* actually, we need to define all constructors */
    basic_csv_string() : std::basic_string<Ch,Tr,A>() { }
    basic_csv_string(const char *ch) : std::basic_string<Ch,Tr,A>(ch) { }
    basic_csv_string(std::basic_string<Ch, Tr, A> str) : std::basic_string<Ch,Tr,A>(str) { }
    
    template<class InputIterator>
    basic_csv_string(InputIterator __beg, InputIterator __end) : std::basic_string<Ch,Tr,A>(__beg, __end) { }
    

    Self substr(size_type start = 0, size_type leng = 0) const;

    template <class ResT>
    std::vector<ResT> *split(std::vector<ResT> &result, Ch c); 

    basic_split_iterator<Self, Ch> create_split_iterator(Ch c);
 };
 

 typedef class basic_csv_string<char> csv_string;
 typedef class basic_split_iterator<csv_string> split_iterator;
};

using namespace ds;
using namespace std;

template <class Ch, class Tr, class A>
basic_csv_string<Ch,Tr,A> basic_csv_string<Ch,Tr,A>::substr(size_type start, size_type leng) const {
    std::string::size_type len = leng?(leng):(Base::length() - start);

    while ((len>0)&&((at(start) == ' ')||(at(start) == '\t'))) {
	start++; len--;
    }
    
    while ((len>0)&&((at(start+len-1)==' ')||(at(start+len-1)=='\r')||(at(start+len-1)=='\n')||(at(start+len-1)=='\t'))) len--;

    return basic_string<Ch,Tr,A>::substr(start,len);
}

template <class Ch, class Tr, class A> template <class ResT>
vector<ResT> *basic_csv_string<Ch,Tr,A>::split(vector<ResT> &result, Ch c) {
	csv_string::size_type pos, nextpos = basic_csv_string<Ch,Tr,A>::find_first_of(c);
	for (pos = 0; nextpos != string::npos; nextpos = basic_csv_string<Ch,Tr,A>::find_first_of(c, pos + 1)) {
	    csv_string word = substr(pos, nextpos - pos);
/*	    if (word.length()>0)*/ result.push_back(word);
	    pos = nextpos + 1;
	}
	csv_string word = substr(pos);
/*	if (word.length()>0)*/ result.push_back(word);

	return &result;
}

template <class Ch, class Tr, class A>
basic_split_iterator<basic_csv_string<Ch, Tr, A>, Ch> basic_csv_string<Ch,Tr,A>::create_split_iterator(Ch c) {
    return basic_split_iterator<basic_csv_string<Ch, Tr, A>, Ch, typename basic_csv_string<Ch, Tr, A>::size_type>(*this, c);
}

#endif /* _DS_STRING_H */