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; |