Kenneth Bruen
3 years ago
commit
5789f53721
5 changed files with 251 additions and 0 deletions
@ -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
|
@ -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. |
@ -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 |
@ -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…
Reference in new issue