Skip to content

Instantly share code, notes, and snippets.

@efruchter
Created January 28, 2019 09:52
Show Gist options
  • Save efruchter/c5c9fc322e70b0b79253e75e0c6aa75e to your computer and use it in GitHub Desktop.
Save efruchter/c5c9fc322e70b0b79253e75e0c6aa75e to your computer and use it in GitHub Desktop.
cheap containers. fixed-width buffers. asserts for bounds checks.
#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