Commit 7960c2dc0a17eb72a74190eadf8f8b39f43c46ae

Authored by Grzegorz Jabłoński
1 parent 5afa692e

Trivially copyable optimization for vector template

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;