#pragma once #include "utility.h" #include #include namespace container { template class Array { public: using data_type = T; using pointer = data_type*; using reference = data_type&; using const_pointer = const pointer; using const_reference = const data_type&; using difference_type = std::ptrdiff_t; using iterator_category = std::forward_iterator_tag; public: class Iterator { public: Iterator(const_pointer input) : m_ptr(input) { } Iterator& operator++() { m_ptr++; return *this; } Iterator operator++(int) { auto it = *this; m_ptr++; return it; } Iterator& operator--() { m_ptr--; return *this; } Iterator operator--(int) { auto it = *this; m_ptr++; return it; } reference operator[](const int index) const { return m_ptr[index]; } pointer operator->() const { return m_ptr; } reference operator*() const { return *m_ptr; } bool operator==(const Iterator& other) const { return m_ptr == other.m_ptr; } bool operator!=(const Iterator& other) const { return m_ptr != other.m_ptr; } private: pointer m_ptr; }; class ConstIterator { public: ConstIterator(const_pointer input) : m_ptr(input) { } ConstIterator& operator++() { m_ptr++; return *this; } ConstIterator operator++(int) { auto it = *this; m_ptr++; return it; } ConstIterator& operator--() { m_ptr--; return *this; } ConstIterator operator--(int) { auto it = *this; m_ptr++; return it; } const_reference operator[](const int index) const { return m_ptr[index]; } const_pointer operator->() const { return m_ptr; } const_reference operator*() const { return *m_ptr; } bool operator==(const ConstIterator& other) const { return m_ptr == other.m_ptr; } bool operator!=(const ConstIterator& other) const { return m_ptr != other.m_ptr; } private: pointer m_ptr; }; public: Array() { m_data = new T[capacity]; } ~Array() { delete[] m_data; } Array(const Array&) = delete; Array(Array&& other) : m_data(other.m_data) { other.m_data = nullptr; } Array& operator=(Array&& other) { if (this != &other) { delete[] m_data; m_data = other.m_data; other.m_data = nullptr; } return *this; } pointer data() { return m_data; } reference operator[](const int index) { return m_data[index]; } const_reference operator[](const int index) const { return m_data[index]; } inline constexpr EntityIndex size() { return capacity; } Iterator begin() { return Iterator(m_data); } Iterator end() { return Iterator(m_data + capacity); } ConstIterator cbegin() const { return ConstIterator(m_data); } ConstIterator cend() const { return ConstIterator(m_data + capacity); } private: pointer m_data; }; template class Array { public: class reference; class const_reference; using data_type = u8; using pointer = reference; using const_pointer = const_reference; using difference_type = std::ptrdiff_t; using iterator_category = std::forward_iterator_tag; public: class reference { friend class Array; reference(data_type* ptr_in, u8 mask_in) : m_ptr(ptr_in) , m_mask(mask_in) { } public: ~reference() { } reference(const reference&) = default; operator bool () const { return !!(*m_ptr & m_mask); } reference& operator=(bool input) { if (input) { *m_ptr |= m_mask; } else { *m_ptr &= m_mask; } return *this; } reference& operator=(const reference& other) { return *this = bool(other); } void flip() { *m_ptr ^= m_mask; } private: data_type* m_ptr; u8 m_mask; }; class const_reference { friend class Array; const_reference(data_type* ptr_in, u8 mask_in) : m_ptr(ptr_in) , m_mask(mask_in) { } public: ~const_reference() { } const_reference(const const_reference&) = delete; operator bool () const { return !!(*m_ptr & m_mask); } const_reference& operator=(bool) = delete; const_reference& operator=(const const_reference& other) = delete; const_reference& operator=(const reference& other) = delete; void flip() = delete; private: const data_type* m_ptr; u8 m_mask; }; class Iterator { public: Iterator(data_type* input, u8 index) : m_ptr(input) , m_currentClusterIndex(index) { } Iterator& operator++() { if (m_currentClusterIndex++ == 7) { m_currentClusterIndex = 0; m_ptr++; } return *this; } Iterator operator++(int) { auto it = *this; if (m_currentClusterIndex++ == 7) { m_ptr++; m_currentClusterIndex = 0; } return it; } Iterator& operator--() { if (m_currentClusterIndex-- == 0) { m_ptr--; m_currentClusterIndex = 7; } return *this; } Iterator operator--(int) { auto it = *this; if (m_currentClusterIndex-- == 0) { m_ptr--; m_currentClusterIndex = 7; } return it; } bool operator[](const int) = delete; reference operator*() const { return reference(m_ptr, 1 << m_currentClusterIndex); } bool operator==(const Iterator& other) const { return (m_ptr == other.m_ptr) && (m_currentClusterIndex == other.m_currentClusterIndex); } bool operator!=(const Iterator& other) const { return (m_ptr != other.m_ptr) || (m_currentClusterIndex != other.m_currentClusterIndex); } private: data_type* m_ptr; u8 m_currentClusterIndex{}; }; class ConstIterator { public: ConstIterator(const data_type* input, u8 index) : m_ptr(input) , m_currentClusterIndex(index) { } ConstIterator& operator++() { if (m_currentClusterIndex++ == 7) { m_currentClusterIndex = 0; m_ptr++; } return *this; } ConstIterator operator++(int) { auto it = *this; if (m_currentClusterIndex++ == 7) { m_ptr++; m_currentClusterIndex = 0; } return it; } ConstIterator& operator--() { if (m_currentClusterIndex-- == 0) { m_ptr--; m_currentClusterIndex = 7; } return *this; } ConstIterator operator--(int) { auto it = *this; if (m_currentClusterIndex-- == 0) { m_ptr--; m_currentClusterIndex = 7; } return it; } bool operator[](const int) = delete; const_reference operator*() const { return const_reference(m_ptr, 1 << m_currentClusterIndex); } bool operator==(const ConstIterator& other) const { return (m_ptr == other.m_ptr) && (m_currentClusterIndex == other.m_currentClusterIndex); } bool operator!=(const ConstIterator& other) const { return (m_ptr != other.m_ptr) || (m_currentClusterIndex != other.m_currentClusterIndex); } private: const data_type* m_ptr; u8 m_currentClusterIndex{}; }; public: Array() { m_data = new data_type[(capacity / 8) + 1]; } ~Array() { delete[] m_data; } Array(const Array&) = delete; Array(Array&& other) : m_data(other.m_data) { other.m_data = nullptr; } Array& operator=(Array&& other) { if (this != &other) { delete[] m_data; m_data = other.m_data; other.m_data = nullptr; } return *this; } data_type* data() { return m_data; } //use readAt() instead reference operator[](int index) { return reference(m_data + (index / 8), 1 << (index % 8)); } inline constexpr EntityIndex size() { return capacity; } bool readAt(const int index) const { return m_data[index / 8] & (1 << (index % 8)); } void setTrueAt(const int index) { m_data[index / 8] |= (1 << (index % 8)); } void setFalseAt(const int index) { m_data[index / 8] &= ~(1 << (index % 8)); } Iterator begin() { return Iterator(m_data, 0); } Iterator end() { return Iterator(m_data + (capacity / 8), capacity % 8); } ConstIterator cbegin() const { return ConstIterator(m_data, 0); } ConstIterator cend() const { return ConstIterator(m_data + (capacity / 8), capacity % 8); } private: data_type* m_data; }; }//namespace