Skip to content

Instantly share code, notes, and snippets.

@Niakr1s
Last active March 12, 2019 07:18
Show Gist options
  • Save Niakr1s/94da251b9232b489b20b203d4448fd13 to your computer and use it in GitHub Desktop.
Save Niakr1s/94da251b9232b489b20b203d4448fd13 to your computer and use it in GitHub Desktop.
simple StrVec impl
#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;
}
#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;
};
#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