Skip to content

Commit

Permalink
Reduce redundant code of prevector and speed it up
Browse files Browse the repository at this point in the history
In prevector.h, the code which like item_ptr(size()) apears in the loop.
Both item_ptr() and size() judge whether values are held directly or
indirectly, but in most cases it is sufficient to make that judgement
once outside the loop.

This PR adds 2 private function fill() which has the loop to initialize
by specified value (or iterator of the other prevector's element),
but don't call item_ptr() in their loop.
Other functions(assign(), constructor, operator=(), insert())
that has similar loop, call fill() instead of original loop.

Also, resize() was changed like fill(), but it calls the default
constructor for that element each time.
  • Loading branch information
AkioNak authored and eklitzke committed Feb 27, 2018
1 parent f0e7aa7 commit e46be25
Showing 1 changed file with 42 additions and 49 deletions.
91 changes: 42 additions & 49 deletions src/prevector.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,29 @@ class prevector {
T* item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }
const T* item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }

void fill(T* dst, size_type count, const T& value) {
for (size_type i = 0; i < count; ++i) {
new(static_cast<void*>(dst + i)) T(value);
}
}

template<typename InputIterator>
void fill(T* dst, InputIterator first, InputIterator last) {
while (first != last) {
new(static_cast<void*>(dst)) T(*first);
++dst;
++first;
}
}

public:
void assign(size_type n, const T& val) {
clear();
if (capacity() < n) {
change_capacity(n);
}
while (size() < n) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(val);
}
_size += n;
fill(item_ptr(0), n, val);
}

template<typename InputIterator>
Expand All @@ -213,11 +226,8 @@ class prevector {
if (capacity() < n) {
change_capacity(n);
}
while (first != last) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(*first);
++first;
}
_size += n;
fill(item_ptr(0), first, last);
}

prevector() : _size(0), _union{{}} {}
Expand All @@ -228,31 +238,23 @@ class prevector {

explicit prevector(size_type n, const T& val = T()) : _size(0) {
change_capacity(n);
while (size() < n) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(val);
}
_size += n;
fill(item_ptr(0), n, val);
}

template<typename InputIterator>
prevector(InputIterator first, InputIterator last) : _size(0) {
size_type n = last - first;
change_capacity(n);
while (first != last) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(*first);
++first;
}
_size += n;
fill(item_ptr(0), first, last);
}

prevector(const prevector<N, T, Size, Diff>& other) : _size(0) {
change_capacity(other.size());
const_iterator it = other.begin();
while (it != other.end()) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(*it);
++it;
}
size_type n = other.size();
change_capacity(n);
_size += n;
fill(item_ptr(0), other.begin(), other.end());
}

prevector(prevector<N, T, Size, Diff>&& other) : _size(0) {
Expand All @@ -263,14 +265,7 @@ class prevector {
if (&other == this) {
return *this;
}
resize(0);
change_capacity(other.size());
const_iterator it = other.begin();
while (it != other.end()) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T(*it);
++it;
}
assign(other.begin(), other.end());
return *this;
}

Expand Down Expand Up @@ -314,15 +309,16 @@ class prevector {
}

void resize(size_type new_size) {
if (size() > new_size) {
size_type cur_size = size();
if (cur_size > new_size) {
erase(item_ptr(new_size), end());
}
if (new_size > capacity()) {
change_capacity(new_size);
}
while (size() < new_size) {
for (T* p = item_ptr(0); cur_size < new_size; cur_size++) {
_size++;
new(static_cast<void*>(item_ptr(size() - 1))) T();
new(static_cast<void*>(p + cur_size)) T();
}
}

Expand All @@ -346,10 +342,11 @@ class prevector {
if (capacity() < new_size) {
change_capacity(new_size + (new_size >> 1));
}
memmove(item_ptr(p + 1), item_ptr(p), (size() - p) * sizeof(T));
T* ptr = item_ptr(p);
memmove(ptr + 1, ptr, (size() - p) * sizeof(T));
_size++;
new(static_cast<void*>(item_ptr(p))) T(value);
return iterator(item_ptr(p));
new(static_cast<void*>(ptr)) T(value);
return iterator(ptr);
}

void insert(iterator pos, size_type count, const T& value) {
Expand All @@ -358,11 +355,10 @@ class prevector {
if (capacity() < new_size) {
change_capacity(new_size + (new_size >> 1));
}
memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T));
T* ptr = item_ptr(p);
memmove(ptr + count, ptr, (size() - p) * sizeof(T));
_size += count;
for (size_type i = 0; i < count; i++) {
new(static_cast<void*>(item_ptr(p + i))) T(value);
}
fill(item_ptr(p), count, value);
}

template<typename InputIterator>
Expand All @@ -373,13 +369,10 @@ class prevector {
if (capacity() < new_size) {
change_capacity(new_size + (new_size >> 1));
}
memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T));
T* ptr = item_ptr(p);
memmove(ptr + count, ptr, (size() - p) * sizeof(T));
_size += count;
while (first != last) {
new(static_cast<void*>(item_ptr(p))) T(*first);
++p;
++first;
}
fill(ptr, first, last);
}

iterator erase(iterator pos) {
Expand Down

0 comments on commit e46be25

Please sign in to comment.