public
Created

A three-member vector. Fast, portable & flexible.

  • Download Gist
mvector.h
C
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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
#include <assert.h>
 
#ifndef _MVECTOR
#define _MVECTOR
 
#define _V_EMPLACE 0
 
template <class T>
struct mVector
{
typedef unsigned int size_type;
typedef T* iterator;
typedef T def_type;
 
inline mVector() : s(NULL), m(NULL), e(NULL){}
inline mVector(size_t sz) : s(NULL), m(NULL){_allocate(sz);}
inline ~mVector(){if(s){_destroy(s, m);free(s);}}
 
inline void _construct(T * _s, T* _e) const {while(_s < _e){new (_s) T();++_s;}}
inline void _destroy(T * _s, T* _e) const {while(_s < _e){_s->~T();++_s;}}
inline void _allocate(size_t sz){if(!sz)return;_destroy(s, m);s = m = (T*)_memalloc(sz);e = &s[sz];assert(s != NULL);}
inline void _check(){if(m == e)_double_capacity();}
 
// _assign() functions (Please change if you want it to support operators)
inline void _assign(T *_m, const T&t) const
{memcpy(_m, &t, sizeof(T)); /*new (_m) T(t);*/ }
 
inline void _copy(T *_m, T *_s, T *_e) const
{memcpy(_m, _s, (_e - _s) * sizeof(T)); /*do{new (_m) T(*_s);}while(++_m, (++_s) < _e);*/}
 
inline size_t size() const {return (m - s);}
inline size_t capacity() const {return (e - s);}
inline void clear(){if(s){_destroy(s, m);m = s;}}
inline bool empty() const {return (s == m);}
 
inline void _double_capacity(){_reserve(capacity() * 2);}
inline void _double_capacity2(T *& t1){t1=(T*)(t1-s);_double_capacity();t1=s+(size_t)t1;}
 
inline void assign(size_t n, T &val){
if(!n)return;clear();
if(is_full(n))_double_capacity();
do{_assign(m, val);}while(++m, --n);
}
 
inline void assign(T *_s, T *_e){if(!_s || !_e)return;clear();copy(_s, (_e - _s));}
inline void operator=(const mVector<T>& vec){assign(vec.begin(), vec.end());}
 
inline T*& get_iterator(){return m;}
inline void set_size(size_t _size){assert(_size < capacity());m = &s[_size];} // warning : unsafe
 
inline void* _memalloc(size_t n) const {return realloc(s, n * sizeof(T));}
 
inline T& at(size_t i) const {assert(i < size());return s[i];}
inline const T &c_back() const {return m[-1];}inline T &back() const {return m[-1];}
inline const T &c_front() const {return s[0];}inline T &front() const {return s[0];}
inline const T *c_begin() const {return &s[0];}inline T *begin() const {return &s[0];}
inline const T *c_end() const {return &m[0];}inline T *end() const {return &m[0];}
 
inline bool enum_object(T *&it) const {if(!it)it = begin() - 1;if((++it) < end())return it;return 0;}
inline bool enum_object2(void *&it) const {return enum_object(*((T**)&it));}
 
inline T *data() const {return &s[0];}
inline T& operator[](size_t i) const {return s[i];}
 
inline void push_back(const T&t){_check();_assign(m, t);++m;}
inline T& push_back2(const T&t){push_back(t);return m[-1];}
 
inline void push_ptr(void* t){_check();_assign(m, ((T*)t)[0]);++m;}
inline T* push_ptr2(void* t){push_ptr(t);return &m[-1];}
 
inline void push_construct(){_check();new (&m[0]) T();++m;}
inline T* push_construct2(){push_construct();return &m[-1];}
 
#if(_V_EMPLACE == 1)
inline void emplace_back(const T&&t){_check();new (&m[0]) T(t);++m;}
inline T& emplace_back2(const T&&t){emplace_back(t);return &m[-1];}
#endif
 
inline void _pop_back(){--m;m->~T();}
inline void pop_back(){if(m != s)_pop_back();}
inline bool pop_back_s(){if(m != s){_pop_back();return true;}return false;}
 
inline T* make_space(size_t n){if((m + n) >= e)_adjust_capacity(n + capacity());T * _s = m;m += n;return _s;}
inline bool is_full(size_t n = 0) const {return ((m + n) >= e);}
 
inline T* copy(const void *d, size_t n){T *_m = make_space(n);_copy(_m, (T*)d, ((T*)d + n));return _m;}
inline void* mcopy(const void *d, size_t sz){assert(!(sz % sizeof(T)));return copy(d, sz / sizeof(T));}
 
inline T* _resize(size_t sz)
{
size_t _size = size();
if(!sz || (sz == _size))return 0;
if(!s){_allocate(sz);return 0;}
if(sz < _size){_destroy(&s[sz], m);m = &s[sz];return 0;}
 
while(sz > capacity())_double_capacity();
m = &s[sz];return &s[_size];
}
 
inline void resize(size_t sz)
{
T *_s = _resize(sz);
if(_s)_construct(_s, m);
}
 
inline void resize(size_t sz, const T&val)
{
T *_s = _resize(sz);
if(_s)do{_assign(_s, val);}while((++_s) != m);
}
inline void _adjust_capacity(size_t sz){size_t _c = capacity();if(_c)while(sz > _c)_c *= 2;else _c = sz;if(_c != capacity())reserve(_c);}
inline void _reserve(size_t sz)
{
if(!sz)sz = 1;
T *t = (T*)_memalloc(sz);
assert(t != NULL);
e = &t[sz];
m = &t[size()];
s = &t[0];
}
 
inline void reserve(size_t sz)
{
if(!sz){if(s)return;}else
if(sz <= capacity())return;
_reserve(sz);
}
 
inline void swap(const mVector<T> &vec)
{
T* vec_s = (vec.s);vec.s = s;s = vec_s;
T* vec_m = (vec.m);vec.m = m;m = vec_m;
T* vec_e = (vec.e);vec.e = e;e = vec_e;
}
 
inline void erase(T *pos){
if((pos < s) || (pos >= m))return;pos->~T();
memcpy(pos, pos + 1, ((--m) - pos) * sizeof(T));
}
 
inline void erase(T *first, T *last){
if((last >= m) || (size() < (last - first)))return;_destroy(first, last);
memcpy(first, last, ((m -= (last - first)) - first) * sizeof(T));
}
 
inline T* insert(T * pos, const T &val){
if(pos > m)return 0;
if(m == e)_double_capacity2(pos);
 
memcpy(pos + 1, pos, (m++ - pos) * sizeof(T));
memcpy(pos, &val, sizeof(T));return pos;
}
inline T* insert(T * pos, size_t n, const T &val){
if(pos > m || !n)return 0;
while((m + n) >= e)_double_capacity2(pos);
T *_pos = pos;
memcpy(pos + n, pos, (m - pos) * sizeof(T));m += n;do{
memcpy(pos, &val, sizeof(T));}while(++pos, --n);
return _pos;
}
inline T* insert(T * pos, T* first, T *last){
if(pos > m || first >= last)return 0;
 
size_t sz = (last - first);
while((m + sz) >= e)_double_capacity2(pos);
 
memcpy(pos + sz, pos, (m - pos) * sizeof(T));m += sz;
memcpy(pos, first, sz * sizeof(T));
return pos;
}
 
inline void shrink_to_fit()
{
if(capacity() == size())return;
T *t = (T*)_memalloc(size());
assert(t != NULL);
m = e = &t[size()];
s = &t[0];
}
 
template<class P>
inline void unique(P f)
{
T *it1 = begin(), *it2;
while(it1 < end())
{
it2 = &it1[1];
while(it2 < end())
{
if(f(*it1, *it2))erase(it2);else ++it2;
}
++it1;
}
}
 
static inline bool _equal(T &v1, T &v2) {return (v1 == v2);}
inline void unique(){return unique(_equal);}
 
union{
struct{T *s, *m, *e;};
struct{T *_first, *_current, *_last;};
};
};
 
#endif

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.