From e5533c2ce9dcb635ab558924dce5f0d54b6fcb14 Mon Sep 17 00:00:00 2001 From: jyxiong Date: Tue, 30 Sep 2025 11:26:18 +0800 Subject: [PATCH] feat(deque): impl deque iterator --- source/tinystl/container/deque.h | 200 +++++++++++++++++++ source/tinystl/iterator/.gitkeep | 0 source/tinystl/iterator/segmented_iterator.h | 20 ++ 3 files changed, 220 insertions(+) create mode 100644 source/tinystl/container/deque.h delete mode 100644 source/tinystl/iterator/.gitkeep create mode 100644 source/tinystl/iterator/segmented_iterator.h diff --git a/source/tinystl/container/deque.h b/source/tinystl/container/deque.h new file mode 100644 index 0000000..fb208d5 --- /dev/null +++ b/source/tinystl/container/deque.h @@ -0,0 +1,200 @@ +#pragma once + +#include +#include +#include + +#include "tinystl/container/vector.h" +#include "tinystl/iterator/segmented_iterator.h" + +namespace tinystl { + +template +struct deque_block_size { + static const DiffType value = + sizeof(ValueType) < 256 ? 4096 / sizeof(ValueType) : 16; +}; + +template < + class ValueType, class Pointer, class Reference, class MapPointer, + class DiffType, + DiffType BlockSize = deque_block_size::value> +class deque_iterator { + using map_iterator = MapPointer; + +public: + using iterator_category = std::random_access_iterator_tag; + using value_type = ValueType; + using difference_type = DiffType; + using reference = Reference; + using pointer = Pointer; + + deque_iterator() : m_iter(nullptr), m_ptr(nullptr) {} + template + requires std::is_convertible_v + deque_iterator(const deque_iterator &it) + : m_iter(it.m_iter), m_ptr(it.m_ptr) {} + + reference operator*() const { return *m_ptr; } + pointer operator->() const { return m_ptr; } + + deque_iterator &operator++() { + if (++m_ptr - *m_iter == m_block_size) { + ++m_iter; + m_ptr = *m_iter; + } + return *this; + } + + deque_iterator operator++(int) { + deque_iterator tmp = *this; + ++(*this); + return tmp; + } + + deque_iterator &operator--() { + if (m_ptr == *m_iter) { + --m_iter; + m_ptr = *m_iter + m_block_size; + } + --m_ptr; + return *this; + } + + deque_iterator operator--(int) { + deque_iterator tmp = *this; + --(*this); + return tmp; + } + + deque_iterator &operator+=(difference_type n) { + if (n != 0) { + n += m_ptr - *m_iter; + if (n > 0) { + m_iter += n / m_block_size; + m_ptr = *m_iter + n % m_block_size; + } else { + difference_type z = m_block_size - 1 - n; + m_iter -= z / m_block_size; + m_ptr = *m_iter + (m_block_size - 1 - z % m_block_size); + } + } + + return *this; + } + + deque_iterator &operator-=(difference_type n) { return *this += -n; } + + deque_iterator operator+(difference_type n) const { + deque_iterator t(*this); + t += n; + return t; + } + + deque_iterator operator-(difference_type n) const { + deque_iterator t(*this); + t -= n; + return t; + } + + reference operator[](difference_type n) const { return *(*this + n); } + + friend deque_iterator operator+(difference_type n, const deque_iterator &it) { + return it + n; + } + + friend difference_type + operator-(const deque_iterator &x, const deque_iterator &y) { + if (x != y) + return (x.m_iter - y.m_iter) * m_block_size + (x.m_ptr - *x.m_iter) - + (y.m_ptr - *y.m_iter); + return 0; + } + + friend bool operator==(const deque_iterator &x, const deque_iterator &y) { + return x.m_ptr == y.m_ptr; + } + + friend std::strong_ordering + operator<=>(const deque_iterator &x, const deque_iterator &y) { + if (x.m_iter < y.m_iter) { + return std::strong_ordering::less; + } + + if (x.m_iter == y.m_iter) { + if constexpr (std::three_way_comparable) { + x.m_ptr <=> y.m_ptr; + } else { + if (x.m_ptr < y.m_ptr) { + return std::strong_ordering::less; + } + + if (x.m_ptr == y.m_ptr) { + return std::strong_ordering::equal; + } + + return std::strong_ordering::greater; + } + } + + return std::strong_ordering::greater; + } + +private: + deque_iterator(map_iterator m, pointer p) noexcept : m_iter(m), m_ptr(p) {} + + template + friend class deque; + + template + friend class deque_iterator; + + template + friend struct segmented_iterator_traits; + +private: + map_iterator m_iter; + pointer m_ptr; + + static const difference_type m_block_size; + ; +}; + +template < + class ValueType, class Pointer, class Reference, class MapPointer, + class DiffType, DiffType BlockSize> +const DiffType deque_iterator< + ValueType, Pointer, Reference, MapPointer, DiffType, + BlockSize>::m_block_size = deque_block_size::value; + +template < + class ValueType, class Pointer, class Reference, class MapPointer, + class DiffType, DiffType BlockSize> +struct segmented_iterator_traits> { +private: + using Iterator = deque_iterator< + ValueType, Pointer, Reference, MapPointer, DiffType, BlockSize>; + +public: + using segment_iterator = MapPointer; + using local_iterator = Pointer; + + static segment_iterator segment(Iterator iter) { return iter.m_iter; } + static local_iterator local(Iterator iter) { return iter.m_ptr; } + + static local_iterator begin(segment_iterator iter) { return *iter; } + static local_iterator end(segment_iterator iter) { + return *iter + Iterator::m_block_size; + } + + static Iterator compose(segment_iterator segment, local_iterator local) { + if (segment && local == end(segment)) { + ++segment; + return _Iterator(segment, *segment); + } + return _Iterator(segment, local); + } +}; + +} // namespace tinystl \ No newline at end of file diff --git a/source/tinystl/iterator/.gitkeep b/source/tinystl/iterator/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/source/tinystl/iterator/segmented_iterator.h b/source/tinystl/iterator/segmented_iterator.h new file mode 100644 index 0000000..5165d93 --- /dev/null +++ b/source/tinystl/iterator/segmented_iterator.h @@ -0,0 +1,20 @@ +#pragma once + +namespace tinystl { + +template +struct segmented_iterator_traits; +/* +{ +using segment_iterator = ...; +using local_iterator = ...; + +static segment_iterator segment(Iter); +static local_iterator local(Iter); +static local_iterator begin(segment_iterator); +static local_iterator end(segment_iterator); +static Iter compose(segment_iterator, local_iterator); +}; +*/ + +} // namespace tinystl