13.39 StrVec.h:
#ifndef STRVEC_H
#define STRVEC_H
#include <string>
#include <memory>
using namespace std;
class StrVec {
public:
StrVec(): elements(nullptr), first_free(nullptr), cap(nullptr) { }
StrVec(const StrVec&);
StrVec(const std::string*, const std::string*);
StrVec(initializer_list<string> lst);
StrVec& operator=(const StrVec&);
~StrVec();
void push_back(const string&);
size_t size() const { return first_free - elements; }
size_t capacity() const { return cap - elements; }
string *begin() const { return elements; }
string *end() const { return first_free;}
void reserve(size_t n) { if (n > capacity()) resize(n); }
void resize(size_t);
string& operator[](size_t n) { return elements[n]; }
private:
static allocator<string> alloc;
void chk_n_alloc()
{ if (size() == capacity() ) reallocate(); }
pair<string*, string*> alloc_n_copy(const string*, const string*);
void free();
void reallocate();
string *elements;
string *first_free;
string *cap;
};
#endif
StrVec.cc:
#include "StrVec.h"
#include <utility>
#include <iterator>
using namespace std;
allocator<string> StrVec::alloc;
void StrVec::push_back(const string &s)
{
chk_n_alloc();
alloc.construct(first_free++, s);
}
pair<string*, string*>
StrVec::alloc_n_copy(const string *b, const string *e)
{
string *data = alloc.allocate(e - b);
return make_pair(data, uninitialized_copy(b, e, data));
}
void StrVec::free()
{
if (elements) {
for (auto p = first_free; p != elements; )
alloc.destroy(--p);
alloc.deallocate(elements, cap - elements);
}
}
StrVec::StrVec(const StrVec &s)
{
auto newdata = alloc_n_copy(s.begin(),