-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVector.h
139 lines (115 loc) · 4.37 KB
/
Vector.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//*********************************************************************************
// Lightweight Arduino Compatible implementation of key STL Vector methods
//*********************************************************************************
//
// Zac Staples
// zacstaples (at) mac (dot) com
//
// 13 June 2014...Friday the 13th...therfore this is probably broken
//
// I needed a data structure to hold refernces and/or pointers as a data
// member of an abstract class for sensors on my robot. That's the point
// I decided I wanted the basic implementation of the STL vector available
// to me in my Arduino sketches. This is not a complete implementation of
// the STL vector, but is designed to be "good enough" to take sketches
// further into OOP.
//
// Based on Stroustrup's basic implementation of vector in Programming 3rd
// edition page 656 and his Simple allocator from The c++ programming
// language, 4th edition. However, I needed info from the following sources
// to implement to allocator to correctly handle placement new in
// the AVR/Arduino environment.
//
// http://www.codeproject.com/Articles/4795/C-Standard-Allocator-An-Introduction-and-Implement
// http://www.glenmccl.com/nd_cmp.htm
// http://www.sourcetricks.com/2008/05/c-placement-new.html#.U5yJF41dW0Q
// http://stackoverflow.com/questions/9805829/arduino-c-destructor
// http://arduino.land/FAQ/index.php?solution_id=1023
//
// Released on the beer license...if this works for you...then remember my
// name an buy me a beer sometime.
#ifndef VECTOR_H
#define VECTOR_H JUN_2014
#include <arduino.h>
//as far as I can tell placement new is not included with AVR or arduino.h
template<typename T>
void* operator new(size_t s, T* v){
return v;
}
//*********************************************************************************
// Allocator for Vector
//*********************************************************************************
template<typename T> struct Simple_alloc {
Simple_alloc() {};
//memory allocation
T* allocate(int n)
{ return reinterpret_cast<T*>(new char[n*sizeof(T)]); }
void deallocate(T* p, int n)
{ delete[] reinterpret_cast<char*>(p); }
//construction/destruction
void construct(T* p, const T& t) { new(p) T(t); }
void destroy(T* p) { p->~T(); }
};
//*********************************************************************************
// Vector
//*********************************************************************************
template<class T, class A = Simple_alloc<T> >
class Vector {
A alloc;
int sz;
T* elem;
int space;
Vector(const Vector&); //private copy constrution because I
//have not got this working yet and don't
//want to expose this for clients who might
//be expecting it.
public:
Vector() : sz(0), elem(0), space(0) {}
Vector(const int s) : sz(0) {
reserve(s);
}
Vector& operator=(const Vector&); //copy assignment
~Vector() {
for(int i=0; i<sz; ++i) alloc.destroy(&elem[i]);
}
T& operator[](int n) { return elem[n]; }
const T& operator[](int n) const { return elem[n]; }
int size() const { return sz; }
int capacity() const { return space; }
void reserve(int newalloc);
void push_back(const T& val);
};
template<class T, class A>
Vector<T, A>& Vector<T, A>::operator=(const Vector& a) {
if(this==&a) return *this;
if(a.size()<=space) { //enough space, no need for new allocation
for(int i=0; i<a.size(); ++i) elem[i]=a[i];
sz = a.size();
return *this;
}
T* p = alloc.allocate(a.size()); //get new memory
for(int i=0; i<a.size(); ++i) {
alloc.construct(&p[i], a[i]); //copy
}
for(int i=0; i<sz; ++i) alloc.destroy(&elem[i]);
space = sz = a.size();
elem = p;
return *this;
}
template<class T, class A> void Vector<T, A>::reserve(int newalloc){
if(newalloc <= space) return; //never decrease space
T* p = alloc.allocate(newalloc);
for(int i=0; i<sz; ++i) alloc.construct(&p[i], elem[i]); //copy
for(int i=0; i<sz; ++i) alloc.destroy(&elem[i]);
alloc.deallocate(elem, space);
elem = p;
space = newalloc;
}
template<class T, class A>
void Vector<T, A>::push_back(const T& val){
if(space == 0) reserve(4); //start small
else if(sz==space) reserve(2*space);
alloc.construct(&elem[sz], val);
++sz;
}
#endif