#pragma once #include "utility.h" //#include #include namespace container { using CapacityType = index_t; using BoolArrayType = u8; template class Array { public: using data_type = T; using pointer = data_type*; using reference = data_type&; using const_pointer = const data_type*; using const_reference = const data_type&; using difference_type = std::ptrdiff_t; using iterator_category = std::forward_iterator_tag; public: class iterator { public: iterator(data_type* 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[](CapacityType index) const { return m_ptr[index]; } pointer operator->() const { return m_ptr; } reference operator*() const { return *m_ptr; } bool operator==(iterator other) const { return m_ptr == other.m_ptr; } bool operator!=(iterator other) const { return m_ptr != other.m_ptr; } private: pointer m_ptr; }; class const_iterator { public: const_iterator(data_type* input) : m_ptr(input) { } const_iterator& operator++() { m_ptr++; return *this; } const_iterator operator++(int) { auto it = *this; m_ptr++; return it; } const_iterator& operator--() { m_ptr--; return *this; } const_iterator operator--(int) { auto it = *this; m_ptr++; return it; } const_reference operator[](CapacityType index) const { return m_ptr[index]; } const_pointer operator->() const { return m_ptr; } const_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: const_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) { 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[](CapacityType index) { return m_data[index]; } const_reference operator[](CapacityType index) const { return m_data[index]; } pointer operator->() { return m_data; } const_pointer operator->() const { return m_data; } reference operator*() { return *m_data; } const_reference operator*() const { return *m_data; } inline constexpr CapacityType size() const { return capacity; } iterator begin() { return iterator(m_data); } iterator end() { return iterator(m_data + capacity); } const_iterator begin() const { return const_iterator(m_data); } const_iterator end() const { return const_iterator(m_data + capacity); } private: pointer m_data; }; template class Array { public: class reference; using pointer = reference; using const_reference = bool; using data_type = BoolArrayType; using difference_type = std::ptrdiff_t; using iterator_category = std::forward_iterator_tag; public: class reference { public: reference(data_type* ptr_in, data_type mask_in) : m_ptr(ptr_in) , m_mask(mask_in) { } ~reference() { } reference(reference&) = default; operator bool () const { return !!(*m_ptr & m_mask); } reference& operator=(bool input) { if (input == true) { *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; } void setTrue() { *m_ptr |= m_mask; } void setFalse() { *m_ptr &= ~m_mask; } private: data_type* const m_ptr; const data_type m_mask; }; class iterator { public: iterator(data_type* input, data_type index) : m_ptr(input) , m_bitIndex(index) { } iterator& operator++() { switch (m_bitIndex++) { case 7: m_bitIndex = 0; m_ptr++; return *this; break; default: return *this; } } iterator operator++(int) { auto it = *this; switch (m_bitIndex++) { case 7: m_bitIndex = 0; m_ptr++; return it; break; default: return it; } } iterator& operator--() { switch (m_bitIndex--) { case 0: m_bitIndex = 7; m_ptr--; return *this; break; default: return *this; } } iterator operator--(int) { auto it = *this; switch (m_bitIndex--) { case 0: m_bitIndex = 7; m_ptr--; return it; break; default: return it; } } reference operator[](CapacityType index) { return reference(m_ptr + (index / 7), m_bitIndex + (index % 8)); } reference operator*() const { return reference(m_ptr, 1 << m_bitIndex); } bool operator==(const iterator& other) const { return (m_ptr == other.m_ptr) && (m_bitIndex == other.m_bitIndex); } bool operator!=(const iterator& other) const { return (m_ptr != other.m_ptr) || (m_bitIndex != other.m_bitIndex); } private: data_type* m_ptr; data_type m_bitIndex{}; }; class const_iterator { public: const_iterator(const data_type* input, data_type index) : m_ptr(input) , m_bitIndex(index) { } const_iterator& operator++() { switch (m_bitIndex++) { case 7: m_bitIndex = 0; m_ptr++; return *this; break; default: return *this; } } const_iterator operator++(int) { auto it = *this; switch (m_bitIndex++) { case 7: m_bitIndex = 0; m_ptr++; return it; break; default: return it; } } const_iterator& operator--() { switch (m_bitIndex--) { case 0: m_bitIndex = 7; m_ptr--; return *this; break; default: return *this; } } const_iterator operator--(int) { auto it = *this; switch (m_bitIndex--) { case 0: m_bitIndex = 7; m_ptr--; return it; break; default: return it; } } const_reference operator[](CapacityType index) const { return (*m_ptr + (index / 8)) & (1 << (index % 8)); } const_reference operator*() const { return *m_ptr & (1 << m_bitIndex); } bool operator==(const const_iterator& other) const { return (m_ptr == other.m_ptr) && (m_bitIndex == other.m_bitIndex); } bool operator!=(const const_iterator& other) const { return (m_ptr != other.m_ptr) || (m_bitIndex != other.m_bitIndex); } private: const data_type* m_ptr; data_type m_bitIndex{}; }; public: Array() { m_data = new data_type[(capacity / 9) + 1]{}; } ~Array() { delete[] m_data; } Array(const Array&) = delete; Array(Array&& other) : m_data(other.m_data) { 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; } reference operator[](CapacityType index) { return reference(m_data + (index / 8), 1 << (index % 8)); } const_reference operator[](CapacityType index) const { return m_data[index / 8] & (1 << (index % 8)); } inline constexpr CapacityType size() { return capacity; } const_reference readAt(CapacityType index) const { return m_data[index / 8] & (1 << (index % 8)); } void setTrueAt(CapacityType index) { m_data[index / 8] |= (1 << (index % 8)); } void setFalseAt(CapacityType 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); } const_iterator begin() const { return const_iterator(m_data, 0); } const_iterator end() const { return const_iterator(m_data + (capacity / 8), capacity % 8); } private: data_type* m_data; }; }//namespace