Commit 70abbf1eceff28090d417f68c09e765882b95de2

Authored by Grzegorz Jabłoński
1 parent 0ca05748

Added vector template with placement new

examples11/04-vectortmpl/makefile 0 → 100644
  1 +all: testvector opnew
  2 +
  3 +testvector: testvector.o
  4 + g++ -g -Wall $^ -o $@
  5 +
  6 +testvector.o: testvector.cpp vector.h
  7 + g++ -g -c -Wall -pedantic $< -o $@
  8 +
  9 +opnew: opnew.o
  10 + g++ -g -Wall $^ -o $@
  11 +
  12 +opnew.o: opnew.cpp
  13 + g++ -g -c -Wall -pedantic $< -o $@
  14 +
  15 +.PHONY: clean
  16 +
  17 +clean:
  18 + -rm testvector.o testvector opnew.o opnew
0 \ No newline at end of file 19 \ No newline at end of file
examples11/04-vectortmpl/opnew.cpp 0 → 100644
  1 +#include <iostream>
  2 +using namespace std;
  3 +
  4 +class Object
  5 +{
  6 +public:
  7 + Object ()
  8 + {
  9 + cout << "Object::Object() called" << endl;
  10 + }
  11 +};
  12 +
  13 +int
  14 +main ()
  15 +{
  16 + Object *p1 = new Object; /* Object::Object() used */
  17 + Object *p2 = new Object (); /* Object::Object() used */
  18 + int *p3 = new int; /* not initialized ! */
  19 + int *p4 = new int (); /* initialized to zero */
  20 + Object *p5 = new Object[7]; /* Object::Object() used 7 times */
  21 + int *p6 = new int[7]; /* not initialized ! */
  22 + int *p7 = new int[7](); /* initialized to zero */
  23 +
  24 +
  25 + if(*p3)
  26 + cout << "*p3 nonzero" <<endl;
  27 + if(*p4)
  28 + cout << "*p4 nonzero" <<endl;
  29 + if(*p6)
  30 + cout << "*p6 nonzero" <<endl;
  31 + if(*p7)
  32 + cout << "*p7 nonzero" <<endl;
  33 +
  34 + delete p1;
  35 + delete p2;
  36 + delete p3;
  37 + delete p4;
  38 + delete[]p5;
  39 + delete[]p6;
  40 + delete[]p7;
  41 +}
examples11/04-vectortmpl/testvector.cpp 0 → 100644
  1 +#include <iostream>
  2 +using namespace std;
  3 +#include "vector.h"
  4 +
  5 +template<class C> void printvector (vector<C> v)
  6 +{
  7 + cout << v << endl;
  8 +}
  9 +
  10 +int
  11 +main ()
  12 +{
  13 + vector<int> a (10);
  14 + cout << a << endl;
  15 + a[0] = 15;
  16 + a[5] = 32;
  17 + vector<int> b(10);
  18 + b=a;
  19 + printvector (b);
  20 + vector<string> c(10);
  21 + vector<string> d(15);
  22 + c[0]="ala";
  23 + c[9]="ma kota";
  24 + c.push_back("ooo");
  25 + c.push_back("ooo");
  26 + c.push_back("ooo");
  27 + c.push_back("ooo");
  28 + c.push_back("ooo");
  29 + c.push_back("ooo");
  30 + c.push_back("ooo");
  31 + c.push_back("ooo");
  32 + c.push_back("ooo");
  33 + c.push_back("ooo");
  34 + c.push_back("ooo");
  35 + c.push_back("ooo");
  36 + c.push_back("ooo");
  37 + c.push_back("ooo");
  38 + c.push_back("ooo");
  39 + c.push_back("ooo");
  40 + c.push_back("ooo");
  41 + c.push_back("ooo");
  42 + c.push_back("ooo");
  43 + c.push_back("ooo");
  44 + c.push_back("ooo");
  45 + c.push_back("ooo");
  46 + c.push_back("ooo");
  47 + c.push_back("ooo");
  48 + c.push_back("ooo");
  49 + c.push_back("ooo");
  50 + c.push_back("ooo");
  51 + c.push_back("ooo");
  52 + c.push_back("ooo");
  53 + c.push_back("ooo");
  54 + c.push_back("ooo");
  55 + c.push_back("ooo");
  56 +
  57 + cout << "About to assign vector" << endl;
  58 + d=c;
  59 + cout << "Vector assigned" << endl;
  60 + printvector(d);
  61 +}
examples11/04-vectortmpl/vector.h 0 → 100644
  1 +#ifndef __VECTOR_H__
  2 +#define __VECTOR_H__
  3 +#include <limits>
  4 +
  5 +template <class C> class vector {
  6 + C *data;
  7 + unsigned int size;
  8 + unsigned int cap;
  9 +
  10 +private:
  11 + static unsigned int round_up_to_power_of_2(unsigned w) {
  12 + const auto bits = std::numeric_limits<unsigned>::digits;
  13 + --w;
  14 + for (unsigned s = 1; s < bits; s *= 2)
  15 + w |= w >> s;
  16 + return ++w;
  17 + };
  18 +
  19 +public:
  20 + class index_out_of_range {};
  21 + explicit vector(unsigned s) {
  22 +
  23 + cap = round_up_to_power_of_2(s);
  24 +
  25 + data = static_cast<C *>(malloc(cap * sizeof(C)));
  26 + if (!data)
  27 + throw bad_alloc();
  28 + size = s;
  29 +
  30 + unsigned i;
  31 + try {
  32 + for (i = 0; i < size; i++)
  33 + new (data + i) C();
  34 + } catch (...) {
  35 + for (unsigned j = 0; j < i; ++j)
  36 + (data + j)->~C();
  37 + free(data);
  38 + throw;
  39 + }
  40 + }
  41 +
  42 + ~vector() {
  43 + for (unsigned j = 0; j < size; ++j)
  44 + (data + j)->~C();
  45 + free(data);
  46 + }
  47 + C &operator[](unsigned int pos) {
  48 + if (pos >= size)
  49 + throw index_out_of_range();
  50 + return data[pos];
  51 + }
  52 + C operator[](unsigned int pos) const {
  53 + if (pos >= size)
  54 + throw index_out_of_range();
  55 + return data[pos];
  56 + }
  57 +
  58 + vector(const vector<C> &s) {
  59 + cap = s.cap;
  60 + data = static_cast<C *>(malloc(cap * sizeof(C)));
  61 + if (!data)
  62 + throw bad_alloc();
  63 + size = s.size;
  64 + unsigned i;
  65 + try {
  66 + for (i = 0; i < size; i++)
  67 + new (data + i) C(s.data[i]);
  68 + } catch (...) {
  69 + for (unsigned j = 0; j < i; ++j)
  70 + (data + j)->~C();
  71 + free(data);
  72 + throw;
  73 + }
  74 + }
  75 +
  76 + void swap(vector<C> &s) {
  77 + C *t1 = s.data;
  78 + unsigned int t2 = s.size;
  79 + unsigned int t3 = s.cap;
  80 + s.data = data;
  81 + s.size = size;
  82 + data = t1;
  83 + size = t2;
  84 + cap = t3;
  85 + }
  86 +
  87 + vector<C> &operator=(const vector<C> &s) {
  88 + if (this == &s)
  89 + return *this;
  90 + vector<C> n(s);
  91 + swap(n);
  92 + return *this;
  93 + }
  94 + friend ostream &operator<<(ostream &o, const vector<C> &v) {
  95 + o << '[';
  96 + for (unsigned i = 0; i < v.size; i++) {
  97 + o << v[i];
  98 + if (i != v.size - 1)
  99 + o << ',';
  100 + };
  101 + o << ']';
  102 + return o;
  103 + }
  104 +
  105 + void push_back(const C &s) {
  106 + if (size < cap) {
  107 + new (data + size) C(s);
  108 + ++size;
  109 + } else {
  110 + if (cap > std::numeric_limits<decltype(size)>::max() / 2)
  111 + throw bad_alloc();
  112 + unsigned int newcap = (cap == 0) ? 1 : 2 * cap;
  113 + C *newdata = static_cast<C *>(malloc(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(data[i]);
  120 + } catch (...) {
  121 + for (unsigned j = 0; j < i; ++j)
  122 + (newdata + j)->~C();
  123 + free(newdata);
  124 + throw;
  125 + }
  126 + new (newdata + size) C(s);
  127 + for (unsigned j = 0; j < size; ++j)
  128 + (data + j)->~C();
  129 + free(data);
  130 + ++size;
  131 + data = newdata;
  132 + cap = newcap;
  133 + }
  134 + }
  135 +};
  136 +#endif /* __VECTOR_H__ */