First commit
This commit is contained in:
commit
5789f53721
5 changed files with 251 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
obj
|
||||
example
|
22
Makefile
Normal file
22
Makefile
Normal file
|
@ -0,0 +1,22 @@
|
|||
CXX?=g++
|
||||
|
||||
.PHONY: debug run clean
|
||||
|
||||
example: obj/example.o
|
||||
${CXX} $^ -o $@
|
||||
|
||||
run: example
|
||||
./example
|
||||
|
||||
debug:
|
||||
COMPILE_FLAGS="-D DEBUG" make -B example
|
||||
|
||||
obj:
|
||||
@if [ ! -d obj ]; then mkdir obj; fi
|
||||
|
||||
obj/%.o: %.cpp | obj
|
||||
${CXX} ${COMPILE_FLAGS} -c $^ -o $@
|
||||
|
||||
clean:
|
||||
@if [ -d obj ]; then echo rm -r obj; rm -r obj; fi
|
||||
@if [ -f example ]; then echo rm example; rm example; fi
|
29
README.md
Normal file
29
README.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
# DynArray: basic dynamic array (list/vector) implementation
|
||||
|
||||
Why? Why not.
|
||||
|
||||
## How to run?
|
||||
|
||||
### Got make?
|
||||
|
||||
```shell
|
||||
make run
|
||||
```
|
||||
|
||||
### No make?
|
||||
|
||||
```shell
|
||||
g++ example.cpp -o example
|
||||
./example
|
||||
```
|
||||
|
||||
### Windows?
|
||||
|
||||
```powershell
|
||||
g++ example.cpp -o example.exe
|
||||
.\example.exe
|
||||
```
|
||||
|
||||
### Windows without `g++`?
|
||||
|
||||
I never compiled something using `msvc` from the terminal. I guess make a new Visual Studio project, copy-paste the files in there and have fun, idk.
|
160
dynarray.hpp
Normal file
160
dynarray.hpp
Normal file
|
@ -0,0 +1,160 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef DEBUG
|
||||
#define TMP_DEBUG_12345 DEBUG
|
||||
#undef DEBUG
|
||||
#include <iostream>
|
||||
using std::cerr;
|
||||
#define DEBUG (cerr << "[DynArray " << this << "] ")
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
class DynArray {
|
||||
private:
|
||||
T* _buffer;
|
||||
size_t _length;
|
||||
size_t _capacity;
|
||||
|
||||
public:
|
||||
explicit DynArray(size_t capacity = 64)
|
||||
: _buffer(new T[capacity])
|
||||
, _length(0)
|
||||
, _capacity(capacity) {
|
||||
#ifdef DEBUG
|
||||
DEBUG << "New array with capacity " << capacity << '\n';
|
||||
#endif
|
||||
}
|
||||
|
||||
~DynArray() {
|
||||
#ifdef DEBUG
|
||||
DEBUG << "Destroyed" << '\n';
|
||||
#endif
|
||||
delete[] _buffer;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return _length;
|
||||
}
|
||||
|
||||
size_t length() const {
|
||||
return _length;
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return length() > 0;
|
||||
}
|
||||
|
||||
size_t capacity() const {
|
||||
return _capacity;
|
||||
}
|
||||
|
||||
void push_back(T element) {
|
||||
if (_length + 1 > _capacity) {
|
||||
#ifdef DEBUG
|
||||
DEBUG << "Push attempt when length and capacity are " << _capacity << ", reallocating" << '\n';
|
||||
#endif
|
||||
T *new_buffer = new T[_capacity * 2];
|
||||
for (size_t i = 0; i < _capacity; ++i) {
|
||||
new_buffer[i] = _buffer[i];
|
||||
}
|
||||
delete[] _buffer;
|
||||
_buffer = new_buffer;
|
||||
_capacity *= 2;
|
||||
}
|
||||
_buffer[_length++] = element;
|
||||
}
|
||||
|
||||
DynArray<T>& operator<<(T element) {
|
||||
push_back(element);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
_length--;
|
||||
}
|
||||
|
||||
T& operator[](size_t index) {
|
||||
return _buffer[index];
|
||||
}
|
||||
|
||||
const T& operator[](size_t index) const {
|
||||
return _buffer[index];
|
||||
}
|
||||
|
||||
// Iterator bullshit
|
||||
class iterator {
|
||||
private:
|
||||
DynArray<T>* _arr;
|
||||
size_t _index;
|
||||
public:
|
||||
// Default constructible
|
||||
iterator() : _arr(nullptr), _index(-1) {}
|
||||
iterator(DynArray<T> &arr, size_t index = 0) : _arr(&arr), _index(index) {}
|
||||
// Copy constructible
|
||||
iterator(const iterator &it) : _arr(it._arr), _index(it._index) {}
|
||||
|
||||
// Copy assignable
|
||||
iterator& operator=(const iterator& it) {
|
||||
_arr = it._arr;
|
||||
_index = it._index;
|
||||
}
|
||||
|
||||
// Comparable
|
||||
bool operator==(const iterator& it) const {
|
||||
return _arr == it._arr && _index == it._index;
|
||||
}
|
||||
|
||||
bool operator!=(const iterator& it) const {
|
||||
return !(*this == it);
|
||||
}
|
||||
|
||||
// Dereferencable
|
||||
T& operator*() {
|
||||
return (*_arr)[_index];
|
||||
}
|
||||
const T& operator*() const {
|
||||
return (*_arr)[_index];
|
||||
}
|
||||
|
||||
T* operator->() {
|
||||
return &((*_arr)[_index]);
|
||||
}
|
||||
const T* operator->() const {
|
||||
return &((*_arr)[_index]);
|
||||
}
|
||||
|
||||
// Can be incremented
|
||||
iterator& operator++() {
|
||||
_index++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator++(int) {
|
||||
auto copy = *this;
|
||||
++*this;
|
||||
return copy;
|
||||
}
|
||||
};
|
||||
|
||||
iterator begin() {
|
||||
return iterator(*this);
|
||||
}
|
||||
const iterator begin() const {
|
||||
return iterator(*this);
|
||||
}
|
||||
|
||||
iterator end() {
|
||||
return iterator(*this, size());
|
||||
}
|
||||
const iterator end() const {
|
||||
return iterator(*this, size());
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef TMP_DEBUG_12345
|
||||
#ifdef DEBUG
|
||||
#undef DEBUG
|
||||
#endif
|
||||
#define DEBUG TMP_DEBUG_12345
|
||||
#undef TMP_DEBUG_12345
|
||||
#endif
|
38
example.cpp
Normal file
38
example.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include <iostream>
|
||||
#include <random>
|
||||
using std::cout;
|
||||
using std::cin;
|
||||
|
||||
#include "dynarray.hpp"
|
||||
|
||||
int main() {
|
||||
size_t n;
|
||||
cout << "How many numbers to generate? ";
|
||||
cin >> n;
|
||||
|
||||
std::default_random_engine r_eng;
|
||||
DynArray<std::default_random_engine::result_type> arr;
|
||||
for (auto i = 0; i < n; i++)
|
||||
{
|
||||
arr << r_eng();
|
||||
}
|
||||
cout << '\n';
|
||||
|
||||
cout << "Size: " << arr.size() << '\n';
|
||||
cout << "Capacity: " << arr.capacity() << '\n';
|
||||
cout << "Elements: [";
|
||||
bool first = true;
|
||||
for (auto elem : arr)
|
||||
{
|
||||
if (!first) {
|
||||
cout << ", ";
|
||||
}
|
||||
else {
|
||||
first = false;
|
||||
}
|
||||
cout << elem;
|
||||
}
|
||||
cout << "]\n";
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue