ArrayList.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #ifndef ARRAYLIST_H
  2. #define ARRAYLIST_H
  3. #include <new>
  4. #include <utility>
  5. #include "utils/StringBuffer.h"
  6. template<typename T, int N>
  7. class ArrayList final {
  8. static_assert(N > 0, "ArrayList size must be positive");
  9. struct alignas(T) Aligned {
  10. char data[sizeof(T)];
  11. };
  12. Aligned data[static_cast<unsigned int>(N)];
  13. int length;
  14. public:
  15. ArrayList() : length(0) {
  16. }
  17. ArrayList(const ArrayList& other) : ArrayList() {
  18. copy(other);
  19. }
  20. ArrayList(ArrayList&& other) : ArrayList() {
  21. move(std::move(other));
  22. other.clear();
  23. }
  24. ~ArrayList() {
  25. clear();
  26. }
  27. ArrayList& operator=(const ArrayList& other) {
  28. if(&other != this) {
  29. clear();
  30. copy(other);
  31. }
  32. return *this;
  33. }
  34. ArrayList& operator=(ArrayList&& other) {
  35. if(&other != this) {
  36. clear();
  37. move(std::move(other));
  38. other.clear();
  39. }
  40. return *this;
  41. }
  42. T* begin() {
  43. return reinterpret_cast<T*>(data);
  44. }
  45. T* end() {
  46. return begin() + length;
  47. }
  48. const T* begin() const {
  49. return reinterpret_cast<const T*>(data);
  50. }
  51. const T* end() const {
  52. return begin() + length;
  53. }
  54. template<typename... Args>
  55. bool add(Args&&... args) {
  56. if(length >= N) {
  57. return true;
  58. }
  59. new(begin() + length++) T(std::forward<Args>(args)...);
  60. return false;
  61. }
  62. T& operator[](int index) {
  63. return begin()[index];
  64. }
  65. const T& operator[](int index) const {
  66. return begin()[index];
  67. }
  68. int getLength() const {
  69. return length;
  70. }
  71. void clear() {
  72. for(int i = 0; i < length; i++) {
  73. begin()[i].~T();
  74. }
  75. length = 0;
  76. }
  77. void remove(int index) {
  78. length--;
  79. if(index != length) {
  80. begin()[index] = std::move(begin()[length]);
  81. }
  82. begin()[length].~T();
  83. }
  84. template<int L>
  85. void toString(StringBuffer<L>& s) const {
  86. s.append("[");
  87. for(int i = 0; i < length - 1; i++) {
  88. s.append(begin()[i]);
  89. s.append(", ");
  90. }
  91. if(length > 0) {
  92. s.append(begin()[length - 1]);
  93. }
  94. s.append("]");
  95. }
  96. private:
  97. void copy(const ArrayList& other) {
  98. for(int i = 0; i < other.length; i++) {
  99. add(other[i]);
  100. }
  101. }
  102. void move(ArrayList&& other) {
  103. for(int i = 0; i < other.length; i++) {
  104. add(std::move(other[i]));
  105. }
  106. }
  107. };
  108. #endif