Add Dirk Luetjen's ssphys libraries and command-line tool
[vss2svn.git] / ssphys / SSLib / tokenarray.h
blobd89708abd905412595edd3ce3f99fc901c5a0e8f
1 // $Id$
2 // Tokenize a string into an array of strings. The delimeter can be either
3 // a set of chars (as a C string) or a Boost regular expression.
4 // Provides a read-only random access iterator. The array is not
5 // sortable, or otherwise writeable.
6 //
7 // Each token in the input string is only extracted when it is asked
8 // for. On construction, the postions of the token delimeters are
9 // found and stored in a std::vector.
11 // Written by C. Ashley Sanders, a.sanders@man.ac.uk, University of
12 // Manchester, 16/7/2004.
14 # ifndef TOKENARRAY_HH_
15 # define TOKENARRAY_HH_
17 # include <iterator>
18 # include <vector>
19 # ifndef ASH_NO_REGEX
20 # include <boost/regex.hpp>
21 # endif
23 namespace ash {
24 template<class CharT = char>
25 class tokenarray {
26 public:
27 typedef tokenarray<CharT> _Myt;
28 typedef typename std::basic_string<CharT> String;
29 # ifndef ASH_NO_REGEX
30 typedef typename boost::basic_regex<CharT> RegExp;
31 # endif
32 typedef typename String::size_type string_size_type;
33 typedef std::vector<std::pair<string_size_type, string_size_type> > tarray;
34 typedef typename tarray::size_type size_type;
36 class const_iterator {
37 public:
38 // This class could derive from std::iterator rather than have all
39 // the typedefs below. However, neither of the two versions of the
40 // STL I have seem to cut the mustard when it comes to std::iterator.
41 typedef std::random_access_iterator_tag iterator_category;
42 typedef String value_type;
43 typedef typename tarray::size_type difference_type;
44 typedef String* pointer;
45 typedef String& reference;
47 private:
48 const tokenarray<CharT> *pvs;
49 difference_type i;
50 public:
51 const_iterator () : pvs(0), i(0) {}
52 const_iterator (const const_iterator &s)
53 : pvs(s.pvs), i(s.i) {};
54 const_iterator (const tokenarray<CharT> *ps, difference_type d)
55 : pvs(ps), i(d) {};
56 const_iterator& operator= (const const_iterator &s) {
57 if (this != &s)
59 pvs = s.pvs;
60 i = s.i;
62 return *this;
64 const_iterator& operator++ () { *this += 1; return *this; };
65 const const_iterator operator++ (int) {
66 const_iterator s (*this);
67 ++*this;
68 return s;
70 const_iterator& operator+= (difference_type d) { i += d; return *this; }
71 const_iterator operator+ (difference_type d) const {
72 const_iterator s (*this);
73 return s += d;
75 const_iterator& operator-- () { *this -= 1; return *this; };
76 const const_iterator operator-- (int) {
77 const_iterator s (*this);
78 --*this;
79 return s;
81 const_iterator& operator-= (difference_type d) { i -= d; return *this; }
82 const_iterator operator- (difference_type d) const {
83 const_iterator s (*this);
84 return s -= d;
86 difference_type operator- (const const_iterator &s) const {
87 return i - s.i;
89 bool operator== (const const_iterator &s) const {
90 return i == s.i;
92 bool operator< (const const_iterator &s) const {
93 return i < s.i;
95 bool operator<= (const const_iterator &s) const {
96 return i <= s.i;
98 bool operator> (const const_iterator &s) const {
99 return i > s.i;
101 bool operator>= (const const_iterator &s) const {
102 return i >= s.i;
104 bool operator!= (const const_iterator &s) const {
105 return i != s.i;
107 const value_type operator[] (difference_type d) const {
108 return (*pvs)[i+d];
110 const value_type operator* () const {
111 return (*pvs)[i];
115 private:
116 tarray vsz;
117 String st;
120 public:
121 tokenarray () {};
122 tokenarray (const String &s, const CharT *pc) : st(s) {
123 string_size_type pos;
124 for (pos = 0; (pos = st.find_first_of (pc, pos)) != String::npos; ++pos)
125 vsz.push_back (std::make_pair (pos, pos+1));
127 # ifndef ASH_NO_REGEX
128 tokenarray (const String &s, const RegExp &re) : st(s) {
129 boost::match_results<typename String::const_iterator> match;
130 typename String::const_iterator pc = st.begin (), pcEnd = st.end ();
131 string_size_type szOffset = 0;
132 while (boost::regex_search (pc, pcEnd, match, re))
134 vsz.push_back (std::make_pair (szOffset + match.position (),
135 szOffset + match.position () + match.length ()));
136 pc = match[0].second;
137 szOffset += match.position() + match.length();
140 # endif // ASH_NO_REGEX
141 tokenarray (const tokenarray& s) : vsz(s.vsz), st(s.st) {};
142 tokenarray& operator= (const tokenarray &s) {
143 tokenarray tmp (s);
144 swap (tmp);
145 return *this;
147 void swap (tokenarray &s) {
148 vsz.swap (s.vsz);
149 st.swap (s.st);
151 String data () const { return st; }
152 void data (const String &s, const CharT *pc) {
153 tokenarray tmp (s, pc);
154 swap (tmp);
156 size_type size () const {
157 return st.empty () ? 0 : vsz.size () + 1;
159 const String operator[] (size_type i) const {
160 // Note: no bounds checking on vsz.
161 string_size_type start = (i) ? vsz[i-1].second : 0;
162 string_size_type len = (i < size ()-1) ? vsz[i].first - start : String::npos;
163 return st.substr (start, len);
165 const_iterator begin () const {
166 return const_iterator (this, 0);
168 const_iterator end () const {
169 return const_iterator (this, size ());
173 } // namespace ash
175 # endif // TOKENARRAY_HH_