Commit 0ce72890a8fe0ed29f6beb5d515868c67c89be14

Authored by Grzegorz Jabłoński
1 parent dea455b3

Refactored vector

examples11/04-vectortmpl/vector.h
@@ -18,6 +18,42 @@ private: @@ -18,6 +18,42 @@ private:
18 return ++w; 18 return ++w;
19 }; 19 };
20 20
  21 + void destroy_array(C *ptr, unsigned int s) {
  22 + for (unsigned j = 0; j < s; ++j)
  23 + (ptr + j)->~C();
  24 + free(ptr);
  25 + }
  26 +
  27 + void resize_before_push() {
  28 + if (size >= cap) {
  29 + if (cap > std::numeric_limits<decltype(size)>::max() / (2 * sizeof(C)))
  30 + throw bad_alloc();
  31 + unsigned int newcap = (cap == 0) ? 1 : 2 * cap;
  32 + C *newdata;
  33 + if constexpr (!std::is_trivially_copyable<C>()) {
  34 + newdata = static_cast<C *>(
  35 + std::aligned_alloc(alignof(C), newcap * sizeof(C)));
  36 + if (!newdata)
  37 + throw bad_alloc();
  38 + unsigned i;
  39 + try {
  40 + for (i = 0; i < size; i++)
  41 + new (newdata + i) C(std::move(data[i]));
  42 + } catch (...) {
  43 + destroy_array(newdata, i);
  44 + throw;
  45 + }
  46 + destroy_array(data, size);
  47 + } else {
  48 + newdata = static_cast<C *>(std::realloc(data, newcap * sizeof(C)));
  49 + if (!newdata)
  50 + throw bad_alloc();
  51 + }
  52 + data = newdata;
  53 + cap = newcap;
  54 + }
  55 + }
  56 +
21 public: 57 public:
22 class index_out_of_range {}; 58 class index_out_of_range {};
23 explicit vector(unsigned s) { 59 explicit vector(unsigned s) {
@@ -34,23 +70,19 @@ public: @@ -34,23 +70,19 @@ public:
34 for (i = 0; i < size; i++) 70 for (i = 0; i < size; i++)
35 new (data + i) C(); 71 new (data + i) C();
36 } catch (...) { 72 } catch (...) {
37 - for (unsigned j = 0; j < i; ++j)  
38 - (data + j)->~C();  
39 - free(data); 73 + destroy_array(data, i);
40 throw; 74 throw;
41 } 75 }
42 } 76 }
43 77
44 - ~vector() {  
45 - for (unsigned j = 0; j < size; ++j)  
46 - (data + j)->~C();  
47 - free(data);  
48 - } 78 + ~vector() { destroy_array(data, size); }
  79 +
49 C &operator[](unsigned int pos) { 80 C &operator[](unsigned int pos) {
50 if (pos >= size) 81 if (pos >= size)
51 throw index_out_of_range(); 82 throw index_out_of_range();
52 return data[pos]; 83 return data[pos];
53 } 84 }
  85 +
54 C operator[](unsigned int pos) const { 86 C operator[](unsigned int pos) const {
55 if (pos >= size) 87 if (pos >= size)
56 throw index_out_of_range(); 88 throw index_out_of_range();
@@ -68,9 +100,7 @@ public: @@ -68,9 +100,7 @@ public:
68 for (i = 0; i < size; i++) 100 for (i = 0; i < size; i++)
69 new (data + i) C(s.data[i]); 101 new (data + i) C(s.data[i]);
70 } catch (...) { 102 } catch (...) {
71 - for (unsigned j = 0; j < i; ++j)  
72 - (data + j)->~C();  
73 - free(data); 103 + destroy_array(data, i);
74 throw; 104 throw;
75 } 105 }
76 } 106 }
@@ -105,44 +135,9 @@ public: @@ -105,44 +135,9 @@ public:
105 } 135 }
106 136
107 void push_back(const C &s) { 137 void push_back(const C &s) {
108 - if (size < cap) {  
109 - new (data + size) C(s);  
110 - ++size;  
111 - } else {  
112 - if (cap > std::numeric_limits<decltype(size)>::max() / (2*sizeof(C)))  
113 - throw bad_alloc();  
114 - unsigned int newcap = (cap == 0) ? 1 : 2 * cap;  
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);  
140 - }  
141 -  
142 - ++size;  
143 - data = newdata;  
144 - cap = newcap;  
145 - } 138 + resize_before_push();
  139 + new (data + size) C(s);
  140 + ++size;
146 } 141 }
147 }; 142 };
148 #endif /* __VECTOR_H__ */ 143 #endif /* __VECTOR_H__ */