#ifndef USU_VECTOR_HPP #define USU_VECTOR_HPP #include #include #include #include #include #include #include #include #include namespace usu { template class vector { public: using size_type = std::size_t; using reference = T &; using pointer = std::shared_ptr; using value_type = T; using resize_type = std::function; static resize_type DEFAULT_RESIZER; static size_type DEFAULT_CAPACITY; vector(); vector(size_type size); vector(resize_type resize); vector(std::initializer_list list); vector(size_type size, resize_type resize); vector(std::initializer_list list, resize_type resize); class iterator { public: using iterator_category = std::forward_iterator_tag; iterator(); iterator(pointer data); iterator(size_type pos, pointer data); iterator(const iterator &obj); iterator(iterator &&obj) noexcept; iterator &operator=(const iterator &rhs); iterator &operator=(iterator &&rhs); bool operator==(const iterator &rhs) const; bool operator!=(const iterator &rhs) const; iterator operator++(); iterator operator--(); iterator operator++(int); iterator operator--(int); value_type operator*(); std::shared_ptr operator->(); private: pointer m_data; size_type m_pos; }; reference operator[](size_type index); void add(T value); void insert(size_type index, T value); void remove(size_type index); void clear(); size_type size(); size_type capacity(); iterator begin(); iterator end(); protected: pointer m_data; size_type m_capacity; size_type m_size; resize_type m_resize; void maybe_resize(); }; template <> class vector : public vector { public: using size_type = std::size_t; using pointer = std::shared_ptr; using resize_type = std::function; vector(); vector(size_type size); vector(resize_type resize); vector(std::initializer_list list); vector(size_type size, resize_type resize); vector(std::initializer_list list, resize_type resize); class reference { public: reference(); reference(size_type pos, pointer data); reference &operator=(bool value); operator bool(); bool operator==(const reference &rhs) const; bool operator!=(const reference &rhs) const; bool get() const; void add(); void sub(); private: size_type m_pos; pointer m_data; }; class iterator { public: using iterator_category = std::forward_iterator_tag; iterator(); iterator(pointer data); iterator(size_type pos, pointer data); iterator(const iterator &obj); iterator(iterator &&obj) noexcept; iterator &operator=(const iterator &rhs); iterator &operator=(iterator &&rhs); bool operator==(const iterator &rhs) const; bool operator!=(const iterator &rhs) const; iterator operator++(); iterator operator--(); iterator operator++(int); iterator operator--(int); reference operator*(); private: reference m_ref; }; reference operator[](size_type index); void add(bool value); void insert(size_type index, bool value); void remove(size_type index); iterator begin(); iterator end(); private: void maybe_resize(); }; template vector::iterator::iterator() : vector::iterator::iterator(nullptr) {} template vector::iterator::iterator(pointer data) : m_data(data), m_pos(0) {} template vector::iterator::iterator(size_type pos, pointer data) : m_data(data), m_pos(pos) {} template vector::iterator::iterator(const iterator &obj) { m_pos = obj.m_pos; m_data = obj.m_data; } template vector::iterator::iterator(iterator &&obj) noexcept { m_pos = obj.m_pos; m_data = obj.m_data; obj.m_pos = 0; obj.m_data = nullptr; } template bool vector::iterator::operator!=(const iterator &rhs) const { return m_pos != rhs.m_pos; } template bool vector::iterator::operator==(const iterator &rhs) const { return m_pos == rhs.m_pos; } template typename vector::iterator vector::iterator::operator++() { m_pos++; return *this; } template typename vector::iterator vector::iterator::operator--() { m_pos--; return *this; } template typename vector::iterator vector::iterator::operator++(int) { iterator it = *this; m_pos++; return it; } template typename vector::iterator vector::iterator::operator--(int) { iterator it = *this; m_pos--; return it; } template typename vector::value_type vector::iterator::operator*() { return m_data[m_pos]; } template std::shared_ptr vector::iterator::operator->() { return std::make_shared(m_data[m_pos]); } template typename vector::resize_type vector::DEFAULT_RESIZER = [](size_type currentCapacity) -> size_type { return currentCapacity * 2; }; template typename vector::size_type vector::DEFAULT_CAPACITY = 10; template vector::vector() : usu::vector(0, DEFAULT_RESIZER) {} template usu::vector::vector(size_type size) : usu::vector(size, DEFAULT_RESIZER) {} template vector::vector(resize_type resize) : usu::vector(0, resize) {} template vector::vector(std::initializer_list list) : usu::vector(list, DEFAULT_RESIZER) {} template vector::vector(std::initializer_list list, resize_type resize) : usu::vector(0, resize) { for (auto i = list.begin(); i < list.end(); ++i) add(*i); } template vector::vector(size_type size, resize_type resize) : m_data(nullptr), m_capacity(DEFAULT_CAPACITY > size ? DEFAULT_CAPACITY : DEFAULT_RESIZER(size)), m_size(size), m_resize(resize) { maybe_resize(); } template void vector::maybe_resize() { if (m_data == nullptr) m_data = std::make_shared(m_capacity); if (m_size >= m_capacity) { m_capacity = std::max(m_capacity == 0 ? 1 : m_resize(m_capacity), m_size); pointer newData = std::make_shared(m_capacity); for (size_type i = 0; i < m_size; ++i) newData[i] = m_data[i]; m_data = newData; } } template void vector::add(T value) { maybe_resize(); m_data[m_size++] = value; } template typename vector::reference vector::operator[](size_type index) { return m_data[index]; } template void vector::insert(size_type index, T value) { maybe_resize(); for (size_type i = m_size; i > index; --i) m_data[i] = m_data[i - 1]; m_data[index] = value; m_size++; } template void vector::remove(size_type index) { for (size_type i = index; i < m_size; ++i) m_data[i] = m_data[i + 1]; m_size--; } template typename vector::iterator vector::begin() { vector::iterator begin(m_data); return begin; } template typename vector::iterator vector::end() { vector::iterator end(m_size, m_data); return end; } template void vector::clear() { m_size = 0; } template typename vector::size_type vector::size() { return m_size; } template typename vector::size_type vector::capacity() { return m_capacity; } } // namespace usu #endif