Commit 7960c2dc0a17eb72a74190eadf8f8b39f43c46ae
1 parent
5afa692e
Trivially copyable optimization for vector template
Showing
2 changed files
with
36 additions
and
16 deletions
examples11/04-vectortmpl/testvector.cpp
... | ... | @@ -15,6 +15,14 @@ main () |
15 | 15 | a[0] = 15; |
16 | 16 | a[5] = 32; |
17 | 17 | vector<int> b(10); |
18 | + a.push_back(4); | |
19 | + a.push_back(5); | |
20 | + a.push_back(6); | |
21 | + a.push_back(7); | |
22 | + a.push_back(8); | |
23 | + a.push_back(9); | |
24 | + a.push_back(10); | |
25 | + a.push_back(11); | |
18 | 26 | b=a; |
19 | 27 | printvector (b); |
20 | 28 | vector<string> c(10); | ... | ... |
examples11/04-vectortmpl/vector.h
1 | 1 | #ifndef __VECTOR_H__ |
2 | 2 | #define __VECTOR_H__ |
3 | +#include <cstring> | |
3 | 4 | #include <limits> |
5 | +#include <type_traits> | |
4 | 6 | |
5 | 7 | template <class C> class vector { |
6 | 8 | C *data; |
... | ... | @@ -110,23 +112,33 @@ public: |
110 | 112 | if (cap > std::numeric_limits<decltype(size)>::max() / 2) |
111 | 113 | throw bad_alloc(); |
112 | 114 | unsigned int newcap = (cap == 0) ? 1 : 2 * cap; |
113 | - C *newdata = static_cast<C *>(std::aligned_alloc(alignof(C), newcap * sizeof(C))); | |
114 | - if (!newdata) | |
115 | - throw bad_alloc(); | |
116 | - unsigned i; | |
117 | - try { | |
118 | - for (i = 0; i < size; i++) | |
119 | - new (newdata + i) C(std::move(data[i])); | |
120 | - } catch (...) { | |
121 | - for (unsigned j = 0; j < i; ++j) | |
122 | - (newdata + j)->~C(); | |
123 | - free(newdata); | |
124 | - throw; | |
115 | + C *newdata; | |
116 | + if constexpr (!std::is_trivially_copyable<C>()) { | |
117 | + newdata = static_cast<C *>( | |
118 | + std::aligned_alloc(alignof(C), newcap * sizeof(C))); | |
119 | + if (!newdata) | |
120 | + throw bad_alloc(); | |
121 | + unsigned i; | |
122 | + try { | |
123 | + for (i = 0; i < size; i++) | |
124 | + new (newdata + i) C(std::move(data[i])); | |
125 | + } catch (...) { | |
126 | + for (unsigned j = 0; j < i; ++j) | |
127 | + (newdata + j)->~C(); | |
128 | + free(newdata); | |
129 | + throw; | |
130 | + } | |
131 | + new (newdata + size) C(s); | |
132 | + for (unsigned j = 0; j < size; ++j) | |
133 | + (data + j)->~C(); | |
134 | + free(data); | |
135 | + } else { | |
136 | + newdata = static_cast<C *>(std::realloc(data, newcap * sizeof(C))); | |
137 | + if (!newdata) | |
138 | + throw bad_alloc(); | |
139 | + new (newdata + size) C(s); | |
125 | 140 | } |
126 | - new (newdata + size) C(s); | |
127 | - for (unsigned j = 0; j < size; ++j) | |
128 | - (data + j)->~C(); | |
129 | - free(data); | |
141 | + | |
130 | 142 | ++size; |
131 | 143 | data = newdata; |
132 | 144 | cap = newcap; | ... | ... |