ar ‹‹
(WORD) m_pointArray.size();
for (vector‹CPoint›::iterator i = m_pointArray.begin(); i!= m_pointArray.end(); ++i)
ar ‹‹ *i;
}
else {
WORD w;
ar ›› w; // pen width
m_nPenWidth = w;
m_pointArray.clear();
ar ›› w; // array size
CPoint point;
m_pointArray.reserve(w);
for (int i = 0; i ‹ w; ++i)
{
ar ›› point; m_pointArray.push_back(
point);
}
}
}
2.4.4 Archive iterators
Since CArchive is defined to work like istream and ostream, it is desirable to define a CArchive_input_iterator and a CArchive_output_iterator that will work like the istream_iterator and ostream_iterator. The loops can then be replaced by a call to the copy algorithm.
2.4.4.1 CArchive_output_iterator
Adapting the output_iterator to become the CArchive_output_iterator is very straightforward. Merely replace ostream with CArchive. The result is as follows:
template ‹class T›
class CArchive_output_iterator:
public
std::iterator‹std::output_iterator_ tag, void, void› {
protected:
CArchive* archive;
public:
CArchive_output_iterator(
CArchive& s): archive(&s) {}
CArchive_output_iterator‹T›&
operator=(const T& value) {
*archive ‹‹ value;
return *this;
}
CArchive_output_iterator‹T›&
operator*() {return *this;}
CArchive_output_iterator‹T›&
operator++() {return *this;}
CArchive_output_iterator‹T›&
operator++(int)
{return *this;}
};
2.4.4.2 CArchive_input_iterator
The loop to read a stroke must terminate after all of the points for that stroke have been read. This is not at the end of the input stream. We will need to pass to the copy algorithm a CArchive_input_iterator that represents the current file position as the first argument, and a CArchive_input_iterator that represents the position at which the copy operator should stop. If we were copying from a standard array, the copy call would look something like this:
copy(start, start+n, destination);
Therefore, we overload the + operator so that a CArchive_input_iterator plus an int will result in a CArchive_input_iterator object that can be used by the equality operator called by the copy algorithm to terminate the loop.
In istream_iterator the data value is extracted from the istream when the iterator object is first created and whenever the ++ operator is called. The dereferencing operator (*) then retrieves the saved value. Since we do not want to extract an object from the CArchive once the specified number of objects have been retrieved, we set a flag to indicate the need to retrieve a new object, and have the actual extraction performed by the * operator. The resulting implementation of CArchive_input_iterator is as follows:
template ‹class T›
class CArchive_input_iterator:
std::iterator‹std::input_iterator_t
ag, T, ptrdiff_t›
{
friend bool operator==(const
CArchive_input_iterator‹T›& x,
const CArchive_input_iterator‹T›& y);
friend bool operator!=(const CArchive_input_iterator‹T›& x,
const
CArchive_input_iterator‹T›& y);
protected:
CArchive* archive;
T value;
bool flag; // True to indicate that value is defined
int count;
// Count of the number of times ++ has been
// applied Or the target value for the number of advances
public:
CArchive_input_iterator(): archive(0), flag(false),
count(0) {}
CArchive_input_iterator(CArchive& s):
archive(& s), count(0), flag (false) {}
const T& operator*() {
if (flag) {
return value; }
else {
*archive ›› value;
flag = true;
return value;
}
}
CArchive_input_iterator‹T›&
operator++() {
++count;
flag = false;
return *this;
}
CArchive_input_iterator‹T›
operator++(int) {