diff --git a/src/app/ArrayList.h b/src/app/ArrayList.h new file mode 100644 index 0000000..94e889f --- /dev/null +++ b/src/app/ArrayList.h @@ -0,0 +1,250 @@ +/** + * @file ArrayList.h + * @author Anatole SCHRAMM-HENRY + * @brief ArrayList type object implementing a List interface + * @version 0.1 + * @date 2025-10-29 + * + * @copyright MIT + * + */ +#ifndef ARRAYLIST_H +#define ARRAYLIST_H +#include "ListInterface.h" + +//The startup size is the list size on creation +#define STARTUP_SIZE 5 +//The reallocation block size corresponds to the size the list is expanded by +#define REALLOC_BLKSIZE 5 + +template +class ArrayList : public ListInterface +{ + /* To be implemented for non pointer objects */ +}; + +template +class ArrayList : public ListInterface +{ + public : + ArrayList(size_t reserve = STARTUP_SIZE) : ListInterface(), _physicalSize(reserve) + { + _array = (T**) malloc(_physicalSize * sizeof(T*)); + } + + virtual ~ArrayList() + { + clear(); + free(_array); + } + + virtual boolean addFirst(T* element) + { + if(!_array) return false; + //If there is no more space available we expand the list + if(_logicalSize == _physicalSize) + { + if(!allocateMore()) + { + delete element; + return false; + } + } + + shiftArray(1); + + _array[0] = element; + _logicalSize++; + + return true; + } + + virtual boolean add(T* element) + { + if(!_array) return false; + //If there is no more space available we expand the list + if(_logicalSize == _physicalSize) + { + if(!allocateMore()) + { + delete element; + return false; + } + } + + _array[_logicalSize] = element; + _logicalSize++; + + return true; + } + + virtual T* remove(size_t index) + { + if(!_array || index >= _logicalSize) return NULL; + + T* p = _array[index]; + + shiftArray(-1, index); + _logicalSize--; + + if(_physicalSize - _logicalSize == REALLOC_BLKSIZE) + { + allocateLess(); + } + + return p; + } + + virtual T* removeFirst() + { + if(!_array || !_logicalSize) return NULL; + + T* p = _array[0]; + + shiftArray(-1); + _logicalSize--; + + if(_physicalSize - _logicalSize == REALLOC_BLKSIZE) + { + allocateLess(); + } + + return p; + } + + virtual T* removeLast() + { + if(!_array || !_logicalSize) return NULL; + + T* p = _array[_logicalSize - 1]; + _logicalSize--; + + if(_physicalSize - _logicalSize == REALLOC_BLKSIZE) + { + allocateLess(); + } + + return p; + } + + virtual T* get(size_t index) + { + if(index >= _logicalSize || !_array) + return NULL; + return _array[index]; + } + + virtual T* operator[](size_t index) + { + return get(index); + } + + virtual T* getFirst() + { + if(!_array || !_logicalSize) return NULL; + + return _array[0]; + } + + virtual T* getLast() + { + if(!_array || !_logicalSize) return NULL; + + return _array[_logicalSize - 1]; + } + + //Contains returns -1 if the element wasn't found or the element's index otherwise + virtual int64_t contains(T* element) + { + for(size_t i(0); i < _logicalSize; i++) + { + if(_array[i] == element || *_array[i] == *element) + return i; + } + + return -1; + } + + virtual size_t count() + { + return _logicalSize; + } + + virtual size_t clear() + { + return dispose(); + } + + virtual size_t dispose() + { + size_t size = _logicalSize; + + if(!_array) return 0; + + for(size_t i(0); i < _logicalSize; i++) + delete _array[i]; + + _logicalSize = 0; + _physicalSize = STARTUP_SIZE; + + void *p = realloc(_array, _physicalSize * sizeof(T*)); + + if(p) + _array = (T**)p; + + return size; + } + + protected : + private : + //Shifts the array place places. If place is positive, it shifts down and + //If place is negative, it shifts up + void shiftArray(int64_t place, size_t from = 0) + { + if(place > 0) + { + for(int64_t i(_logicalSize + place - 1); i > from; i--) + _array[i] = _array[i-1]; + } + else if(place < 0) + { + for(int64_t i(from); i < _logicalSize - place - 2; i++) + _array[i] = _array[i+1]; + } + } + + boolean allocateMore() + { + void *p = realloc(_array, (_physicalSize + REALLOC_BLKSIZE) * sizeof(T*)); + + if(p) + { + _physicalSize += REALLOC_BLKSIZE; + _array = (T**)p; + } + + else + return false; + return true; + } + + boolean allocateLess() + { + void *p = realloc(_array, (_physicalSize - REALLOC_BLKSIZE) * sizeof(T*)); + + if(p) + { + _physicalSize -= REALLOC_BLKSIZE; + _array = (T**)p; + } + + else + return false; + return true; + } + + T**_array = NULL; + size_t _logicalSize = 0, _physicalSize; +}; + +#endif //ARRAYLIST_H diff --git a/src/app/ListInterface.h b/src/app/ListInterface.h new file mode 100644 index 0000000..d52967a --- /dev/null +++ b/src/app/ListInterface.h @@ -0,0 +1,36 @@ +/** + * @file ListInterface.h + * @author Anatole SCHRAMM-HENRY + * @brief Interface defining all the needed function of a List type object + * @version 0.1 + * @date 2025-10-29 + * + * @copyright MIT + * + */ +#ifndef LISTINTERFACE__H +#define LISTINTERFACE__H + +template +class ListInterface +{ + public: + virtual boolean addFirst(T element) = 0; + virtual boolean add(T element) = 0; + virtual T remove(size_t index) = 0; + virtual T removeFirst() = 0; + virtual T removeLast() = 0; + virtual T get(size_t index) = 0; + virtual T operator[](size_t index) = 0; + virtual T getFirst() = 0; + virtual T getLast() = 0; + virtual int64_t contains(T element) = 0; + virtual size_t count() = 0; + virtual size_t clear() = 0; + virtual size_t dispose() = 0; + + protected: + private: +}; + +#endif //LISTINTERFACE__H \ No newline at end of file