|
#ifndef STRVEC_H |
|
#define STRVEC_H |
|
#include <memory> |
|
#include <string> |
|
#include <utility> |
|
#include <initializer_list> |
|
class StrVec |
|
{ |
|
public: |
|
StrVec(): |
|
elements(nullptr), first_free(nullptr), cap(nullptr) {} |
|
StrVec(std::initializer_list<std::string> sl) |
|
{ |
|
auto ptr_pair = alloc_n_copy(sl.begin(), sl.end()); |
|
elements = ptr_pair.first; |
|
first_free = cap = ptr_pair.second; |
|
} |
|
|
|
StrVec(const StrVec &sv) |
|
{ |
|
auto ptr_pair = alloc_n_copy(sv.begin(), sv.end()); |
|
elements = ptr_pair.first; |
|
first_free = cap = ptr_pair.second; |
|
} |
|
StrVec &operator=(const StrVec &sv) |
|
{ |
|
auto ptr_pair = alloc_n_copy(sv.begin(), sv.end()); |
|
free(); |
|
elements = ptr_pair.first; |
|
first_free = cap = ptr_pair.second; |
|
return *this; |
|
} |
|
~StrVec() |
|
{ |
|
free(); |
|
} |
|
|
|
void push_back(const std::string &s) |
|
{ |
|
chk_n_alloc(); |
|
alloc.construct(first_free++, s); |
|
} |
|
std::string *begin() const |
|
{ |
|
return elements; |
|
} |
|
std::string *end() const |
|
{ |
|
return first_free; |
|
} |
|
std::size_t size() const |
|
{ |
|
return first_free - elements; |
|
} |
|
std::size_t capacity() const |
|
{ |
|
return cap - elements; |
|
} |
|
void reserve(const std::size_t &sz); |
|
void resize(const std::size_t &sz, const std::string &s); |
|
private: |
|
static std::allocator<std::string> alloc; |
|
|
|
void chk_n_alloc() |
|
{ |
|
if (first_free == cap) |
|
reallocate(); |
|
} |
|
std::pair<std::string *, std::string *> alloc_n_copy |
|
(const std::string *b, const std::string *e) |
|
{ |
|
auto new_elem = alloc.allocate(e - b); |
|
return {new_elem, std::uninitialized_copy(b, e, new_elem)}; |
|
} |
|
void free(); |
|
void reallocate(); |
|
std::string *elements; |
|
std::string *first_free; |
|
std::string *cap; |
|
}; |
|
|
|
#endif // STRVEC_H |