The following code uses the Vec class, which was implemented
in Chapter 11, in order to implement a string-like class
called Str. At the core of the implementation of the
Str class is a private data member which is
defined as a vector of characters (i.e. Vec<char>
data).
Str class
#ifndef STR_H
#define STR_H
#include <algorithm>
#include <cstring>
#include <iterator>
#include "Vec.h"
class Str {
// input operator implemented in 12.3.2/216
friend std::istream& operator>>(std::istream&, Str&);
public:
typedef Vec<char>::size_type size_type;
typedef char* iterator;
typedef const char* const_iterator;
Str() { }
Str(size_type n, char c): data(n, c) { }
Str(const char* cp) {
std::copy(cp, cp + std::strlen(cp), std::back_inserter(data));
}
template <class In> Str(In i, In j) {
std::copy(i, j, std::back_inserter(data));
}
char& operator[](size_type i) { return data[i]; }
const char& operator[](size_type i) const { return data[i]; }
size_type size() const { return data.size(); }
iterator begin() { return data.begin(); }
const_iterator begin() const { return data.begin(); }
iterator end() { return data.end(); }
const_iterator end() const { return data.end(); }
Str& operator+=(const Str& s) {
std::copy(s.data.begin(), s.data.end(),
std::back_inserter(data));
return *this;
}
private:
Vec<char> data;
};
// output operator implemented in 12.3.2/216
std::ostream& operator<<(std::ostream&, const Str&);
// String concatentation operator.
Str operator+(const Str&, const Str&);
inline bool operator<(const Str& lhs, const Str& rhs)
{
return std::lexicographical_compare(lhs.begin(), lhs.end(),
rhs.begin(), rhs.end());
}
// Other relational operators (e.g. >, <=, >=) can be implemented similarly.
inline bool operator==(const Str& lhs, const Str& rhs)
{
return lhs.size() == rhs.size() &&
std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
inline bool operator!=(const Str& lhs, const Str& rhs)
{
return !(lhs == rhs);
}
#endif
Str class
#include <cctype>
#include <iostream>
using std::isspace;
#include "Str.h"
using std::istream;
using std::ostream;
Str operator+(const Str& s, const Str& t)
{
Str r = s;
r += t;
return r;
}
ostream& operator<<(ostream& os, const Str& s)
{
for (Str::size_type i = 0; i != s.size(); ++i)
os << s[i];
return os;
}
istream& operator>>(istream& is, Str& s)
{
// obliterate existing value(s)
s.data.clear();
// read and discard leading whitespace
char c;
while (is.get(c) && isspace(c))
; // nothing to do, except testing the condition
// if still something to read, do so until next whitespace character
if (is) {
do
// Note that 'data' is private in class 'Str'.
// Therefore 'istream& operator>>(istream& is, Str& s)'
// must be declared as a friend in the Str class.
s.data.push_back(c);
while (is.get(c) && !isspace(c));
// if we read whitespace, then put it back on the stream
if (is)
is.unget();
}
return is;
}
Last modified: Wed Mar 12 14:04:43 2003