Created
January 28, 2019 09:52
-
-
Save efruchter/c5c9fc322e70b0b79253e75e0c6aa75e to your computer and use it in GitHub Desktop.
cheap containers. fixed-width buffers. asserts for bounds checks.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <assert.h> | |
namespace oats { | |
template <class T> | |
struct dynamic_array { | |
T * arr; | |
dynamic_array(); | |
dynamic_array(const int initial_capacity); | |
~dynamic_array(); | |
int size() const { return _size; } | |
int capacity() const { return _capacity; } | |
void add(T t); | |
T remove_at(int index_to_remove); | |
T &operator[] (int); | |
private: | |
int _size, _capacity; | |
}; | |
template<class T> | |
inline dynamic_array<T>::dynamic_array() { | |
_size = 0; | |
_capacity = 0; | |
arr = nullptr; | |
} | |
template<class T> | |
inline dynamic_array<T>::dynamic_array(const int initial_capacity) { | |
_size = 0; | |
_capacity = initial_capacity; | |
arr = (T*)malloc(sizeof(T) * initial_capacity); | |
assert(arr != nullptr); | |
} | |
template<class T> | |
inline dynamic_array<T>::~dynamic_array() { | |
if (arr != nullptr) { | |
free(arr); | |
arr = nullptr; | |
} | |
} | |
template<class T> | |
void dynamic_array<T>::add(T t) { | |
if (_size == _capacity) { | |
if (_capacity == 0) { | |
_capacity = 1; | |
arr = (T*)malloc(sizeof(T)); | |
assert(arr != nullptr); | |
} else { | |
_capacity *= 2; | |
T* newArr = (T*)realloc(arr, sizeof(T) * _capacity); | |
assert(newArr != nullptr); | |
arr = newArr; | |
} | |
} | |
arr[_size] = t; | |
_size++; | |
} | |
template<class T> | |
T dynamic_array<T>::remove_at(int index_to_remove) { | |
assert(index_to_remove >= 0); | |
assert(index_to_remove < size); | |
assert(_size > 0); | |
T t = arr[index_to_remove]; | |
memmove(arr + index_to_remove, arr + index_to_remove + 1, sizeof(T) * (_size - 1)); | |
_size--; | |
} | |
template<class T> | |
inline T & dynamic_array<T>::operator[](int index) { | |
assert(index >= 0); | |
assert(index < _size); | |
return arr[index]; | |
} | |
template <class T, int _capacity> | |
struct array { | |
T arr[_capacity]{}; | |
int size() const { return _size; } | |
int capacity() const { return _capacity; } | |
void add(T t); | |
T remove_at(int index_to_remove); | |
T &operator[] (int); | |
private: | |
int _size = 0; | |
}; | |
template<class T, int _capacity> | |
void array<T, _capacity>::add(T t) { | |
assert(_size != _capacity); | |
arr[_size] = t; | |
_size++; | |
} | |
template<class T, int _capacity> | |
T array<T, _capacity>::remove_at(int index_to_remove) { | |
assert(index_to_remove >= 0); | |
assert(index_to_remove < _size); | |
assert(_size > 0); | |
T t = arr[index_to_remove]; | |
memmove(arr + index_to_remove, arr + index_to_remove + 1, sizeof(T) * (_size - 1)); | |
_size--; | |
return t; | |
} | |
template<class T, int _capacity> | |
inline T & array<T, _capacity>::operator[](const int index) { | |
assert(index >= 0); | |
assert(index < _size); | |
return arr[index]; | |
} | |
template <class T, int _capacity> | |
class queue { | |
public: | |
T buffer[_capacity]{}; | |
inline int size() const { return _size; } | |
void enqueue(T t); | |
T dequeue(); | |
T &operator[] (int) const; | |
inline bool has_next() const { return _size > 0; } | |
inline int capacity() const { return _capacity; } | |
private: | |
int _size = 0; | |
int _front_index = 0; | |
}; | |
template<class T, int _capacity> | |
inline void queue<T, _capacity>::enqueue(T t) { | |
assert(_size != _capacity); | |
int i = (_front_index + _size) % _capacity; | |
buffer[i] = t; | |
_size++; | |
} | |
template<class T, int _capacity> | |
inline T queue<T, _capacity>::dequeue() { | |
assert(_size > 0); | |
T t = buffer[_front_index]; | |
_front_index = (_front_index + 1) % _capacity; | |
_size--; | |
return t; | |
} | |
template<class T, int _capacity> | |
inline T & queue<T, _capacity>::operator[](int index) const { | |
assert(size > 0); | |
assert(index < size); | |
return buffer[(_front_index + index) % _size]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment