diff --git a/include/frg/vector.hpp b/include/frg/vector.hpp index 729fa92..716943d 100644 --- a/include/frg/vector.hpp +++ b/include/frg/vector.hpp @@ -1,6 +1,8 @@ #ifndef FRG_VECTOR_HPP #define FRG_VECTOR_HPP +#include +#include #include #include @@ -14,6 +16,103 @@ class vector { using value_type = T; using reference = value_type&; + template + struct Iterator { + using iterator_category = std::random_access_iterator_tag; + using iterator_concept = std::contiguous_iterator_tag; + using value_type = std::remove_cv_t; + using element_type = Element; + using difference_type = ptrdiff_t; + using pointer = Element *; + using reference = Element &; + + constexpr Iterator() noexcept = default; + constexpr explicit Iterator(pointer ptr) noexcept : ptr_{ptr} {} + + template + requires std::convertible_to + constexpr Iterator(const Iterator &other) noexcept : ptr_(other.ptr_) {} + + constexpr reference operator*() const noexcept { return *ptr_; } + constexpr pointer operator->() const noexcept { return ptr_; } + + constexpr Iterator &operator++() noexcept { + ++ptr_; + return *this; + } + + constexpr Iterator operator++(int) noexcept { + Iterator tmp = *this; + ++ptr_; + return tmp; + } + + constexpr Iterator &operator--() noexcept { + --ptr_; + return *this; + } + + constexpr Iterator operator--(int) noexcept { + Iterator tmp = *this; + --ptr_; + return tmp; + } + + constexpr Iterator &operator+=(difference_type offset) noexcept { + ptr_ += offset; + return *this; + } + + constexpr Iterator operator+(difference_type offset) const noexcept { + return Iterator(ptr_ + offset); + } + + constexpr friend Iterator operator+(difference_type offset, const Iterator &it) noexcept { + return Iterator(it.ptr_ + offset); + } + + constexpr Iterator &operator-=(difference_type offset) noexcept { + ptr_ -= offset; + return *this; + } + + constexpr Iterator operator-(difference_type offset) const noexcept { + return Iterator(ptr_ - offset); + } + + template + requires requires(pointer p1, OtherElement *p2) { p1 - p2; } + constexpr difference_type operator-(const Iterator &other) const noexcept { + return ptr_ - other.ptr_; + } + + constexpr reference operator[](difference_type offset) const noexcept { + return ptr_[offset]; + } + + template + requires requires(pointer p1, OtherElement *p2) { p1 <=> p2; } + constexpr auto operator<=>(const Iterator &other) const noexcept { + return ptr_ <=> other.ptr_; + } + + template + requires requires(pointer p1, OtherElement *p2) { p1 == p2; } + constexpr bool operator==(const Iterator &other) const noexcept { + return ptr_ == other.ptr_; + } + + template friend struct Iterator; + + private: + pointer ptr_ = nullptr; + }; + + using iterator = Iterator; + using const_iterator = Iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + friend constexpr void swap(vector &a, vector &b) { using std::swap; swap(a._allocator, b._allocator); @@ -93,20 +192,52 @@ class vector { return size() == 0; } - constexpr T *begin() { - return _elements; + constexpr iterator begin() { + return iterator(_elements); } - constexpr const T *begin() const { - return _elements; + constexpr const_iterator begin() const { + return const_iterator(_elements); + } + + constexpr const_iterator cbegin() const { + return const_iterator(_elements); + } + + constexpr iterator end() { + return iterator(_elements + _size); + } + + constexpr const_iterator end() const { + return const_iterator(_elements + _size); + } + + constexpr const_iterator cend() const { + return const_iterator(_elements + _size); + } + + constexpr reverse_iterator rbegin() { + return reverse_iterator(end()); + } + + constexpr const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + constexpr const_reverse_iterator crbegin() const { + return const_reverse_iterator(cend()); + } + + constexpr reverse_iterator rend() { + return reverse_iterator(begin()); } - constexpr T *end() { - return _elements + _size; + constexpr const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); } - constexpr const T *end() const { - return _elements + _size; + constexpr const_reverse_iterator crend() const { + return const_reverse_iterator(cbegin()); } constexpr T &front() {