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,6 +15,14 @@ main () | ||
15 | a[0] = 15; | 15 | a[0] = 15; |
16 | a[5] = 32; | 16 | a[5] = 32; |
17 | vector<int> b(10); | 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 | b=a; | 26 | b=a; |
19 | printvector (b); | 27 | printvector (b); |
20 | vector<string> c(10); | 28 | vector<string> c(10); |
examples11/04-vectortmpl/vector.h
1 | #ifndef __VECTOR_H__ | 1 | #ifndef __VECTOR_H__ |
2 | #define __VECTOR_H__ | 2 | #define __VECTOR_H__ |
3 | +#include <cstring> | ||
3 | #include <limits> | 4 | #include <limits> |
5 | +#include <type_traits> | ||
4 | 6 | ||
5 | template <class C> class vector { | 7 | template <class C> class vector { |
6 | C *data; | 8 | C *data; |
@@ -110,23 +112,33 @@ public: | @@ -110,23 +112,33 @@ public: | ||
110 | if (cap > std::numeric_limits<decltype(size)>::max() / 2) | 112 | if (cap > std::numeric_limits<decltype(size)>::max() / 2) |
111 | throw bad_alloc(); | 113 | throw bad_alloc(); |
112 | unsigned int newcap = (cap == 0) ? 1 : 2 * cap; | 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 | ++size; | 142 | ++size; |
131 | data = newdata; | 143 | data = newdata; |
132 | cap = newcap; | 144 | cap = newcap; |