Last active
March 12, 2019 07:18
-
-
Save Niakr1s/94da251b9232b489b20b203d4448fd13 to your computer and use it in GitHub Desktop.
simple StrVec impl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include "Strvec.h" | |
using namespace std; | |
int main(int argc, char *argv[]) | |
{ | |
StrVec svec("Root"); | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
svec.push_back("Hi"); | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
svec.push_back("Hi"); | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
svec.push_back("Hi"); | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
svec.push_back("Hi"); | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
svec.push_back("Hi"); | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
svec.push_back("Hi"); | |
svec.shrink_to_fit(); | |
cout << "shrinked\n"; | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
svec.push_back("Hi"); | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
svec.free(); | |
cout << "freed\n"; | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
svec.push_back("Hi"); | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
svec.push_back("Hi"); | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
svec.push_back("Hi"); | |
svec.print(); | |
cout << "size: " << svec.size() << ", cap: " << svec.capacity() << "\n"; | |
auto new_vec(svec); | |
svec.print(); | |
new_vec.print(); | |
cout << "op=\n"; | |
new_vec = svec; | |
new_vec.print(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "StrVec.h" | |
StrVec::StrVec(const string &s) : StrVec::StrVec() | |
{ | |
push_back(s); | |
} | |
StrVec::~StrVec() { free(); }; | |
StrVec::StrVec(const StrVec &rhs) : elements(rhs.elements), first_free(rhs.first_free), cap(rhs.cap) | |
{ | |
auto n = allocate_n_copy(elements, first_free); | |
elements = n.first; | |
cap = first_free = n.second; | |
}; | |
StrVec &StrVec::operator=(const StrVec &rhs) | |
{ | |
auto n = allocate_n_copy(rhs.elements, rhs.first_free); | |
free(); | |
elements = n.first; | |
cap = first_free = n.second; | |
return *this; | |
}; | |
void StrVec::push_back(const string &s) | |
{ | |
chk_n_alloc(); | |
alloc.construct(first_free++, s); | |
}; | |
void StrVec::pop_back() | |
{ | |
alloc.destroy(--first_free); | |
}; | |
void StrVec::shrink_to_fit() | |
{ | |
if (has_space()) | |
reallocate(true); | |
}; | |
void StrVec::free() | |
{ | |
if (elements) | |
{ | |
for (auto p = first_free; p != elements;) | |
alloc.destroy(--p); | |
alloc.deallocate(elements, cap - elements); | |
} | |
elements = nullptr; | |
first_free = nullptr; | |
cap = nullptr; | |
} | |
void StrVec::print() | |
{ | |
for (auto it = begin(); it != end(); ++it) | |
{ | |
cout << *it << ", "; | |
} | |
cout << "\n"; | |
} | |
pair<string *, string *> StrVec::allocate_n_copy(const string *beg, const string *end) | |
{ | |
auto b = alloc.allocate(end - beg); | |
auto e = uninitialized_copy(beg, end, b); | |
return {b, e}; | |
}; | |
void StrVec::chk_n_alloc() | |
{ | |
if (!has_space()) | |
reallocate(); | |
}; | |
void StrVec::reallocate(bool fit) | |
{ | |
auto new_cap = fit ? size() : (size() ? size() * 2 : 1); | |
auto b = alloc.allocate(new_cap); | |
auto it = b; | |
for (auto elem = elements; elem != first_free; ++elem, ++it) | |
alloc.construct(it, move(*elem)); | |
free(); | |
elements = b; | |
first_free = it; | |
cap = elements + new_cap; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if !defined(STRVEC_H) | |
#define STRVEC_H | |
#include <string> | |
#include <iostream> | |
#include <memory> | |
#include <cassert> | |
#include <utility> | |
using namespace std; | |
struct StrVec | |
{ | |
public: | |
StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) {} | |
StrVec(const string &s); | |
~StrVec(); | |
StrVec(const StrVec &rhs); | |
StrVec &operator=(const StrVec &rhs); | |
size_t size() { return first_free - elements; }; | |
size_t capacity() { return cap - elements; }; | |
string *begin() { return elements; }; | |
string *end() { return first_free; }; | |
void push_back(const string &s); | |
void pop_back(); | |
void shrink_to_fit(); | |
void free(); | |
void print(); | |
private: | |
allocator<string> alloc; | |
string *elements, *first_free, *cap; | |
bool has_space() { return cap != first_free; }; | |
pair<string *, string *> allocate_n_copy(const string *beg, const string *end); | |
void chk_n_alloc(); | |
void reallocate(bool fit = false); | |
}; | |
#endif // STRVEC_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment