diff --git a/AK/FixedArray.h b/AK/FixedArray.h index 38004fc1299..efcccfcedde 100644 --- a/AK/FixedArray.h +++ b/AK/FixedArray.h @@ -26,8 +26,9 @@ #pragma once +#include #include -#include +#include namespace AK { @@ -142,13 +143,14 @@ public: ::swap(m_size, other.m_size); } - using Iterator = VectorIterator; - Iterator begin() { return Iterator(*this, 0); } - Iterator end() { return Iterator(*this, size()); } + using ConstIterator = SimpleIterator; + using Iterator = SimpleIterator; - using ConstIterator = VectorIterator; - ConstIterator begin() const { return ConstIterator(*this, 0); } - ConstIterator end() const { return ConstIterator(*this, size()); } + ConstIterator begin() const { return ConstIterator::begin(*this); } + Iterator begin() { return Iterator::begin(*this); } + + ConstIterator end() const { return ConstIterator::end(*this); } + Iterator end() { return Iterator::end(*this); } operator Bytes() { return bytes(); } operator ReadonlyBytes() const { return bytes(); } diff --git a/AK/Forward.h b/AK/Forward.h index 6550f7d39fe..9d9019cb7e6 100644 --- a/AK/Forward.h +++ b/AK/Forward.h @@ -61,6 +61,12 @@ class CircularDuplexStream; template class Span; +template +class Array; + +template +class SimpleIterator; + using ReadonlyBytes = Span; using Bytes = Span; @@ -123,6 +129,7 @@ class Vector; } +using AK::Array; using AK::Atomic; using AK::Badge; using AK::Bitmap; diff --git a/AK/Iterator.h b/AK/Iterator.h new file mode 100644 index 00000000000..1d424b46709 --- /dev/null +++ b/AK/Iterator.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace AK { + +template +class SimpleIterator { +public: + friend Container; + + constexpr bool is_end() const { return m_index == SimpleIterator::end(m_container).m_index; } + constexpr size_t index() const { return m_index; } + + constexpr bool operator==(SimpleIterator other) const { return m_index == other.m_index; } + constexpr bool operator!=(SimpleIterator other) const { return m_index != other.m_index; } + constexpr bool operator<(SimpleIterator other) const { return m_index < other.m_index; } + constexpr bool operator>(SimpleIterator other) const { return m_index > other.m_index; } + constexpr bool operator<=(SimpleIterator other) const { return m_index <= other.m_index; } + constexpr bool operator>=(SimpleIterator other) const { return m_index >= other.m_index; } + + constexpr SimpleIterator operator+(ptrdiff_t delta) const { return SimpleIterator { m_container, m_index + delta }; } + constexpr SimpleIterator operator-(ptrdiff_t delta) const { return SimpleIterator { m_container, m_index - delta }; } + + constexpr ptrdiff_t operator-(SimpleIterator other) const { return static_cast(m_index) - other.m_index; } + + constexpr SimpleIterator operator++() + { + ++m_index; + return *this; + } + constexpr SimpleIterator operator++(int) + { + ++m_index; + return SimpleIterator { m_container, m_index - 1 }; + } + + constexpr SimpleIterator operator--() + { + --m_index; + return *this; + } + constexpr SimpleIterator operator--(int) + { + --m_index; + return SimpleIterator { m_container, m_index + 1 }; + } + + constexpr const ValueType& operator*() const { return m_container[m_index]; } + constexpr ValueType& operator*() { return m_container[m_index]; } + + constexpr const ValueType* operator->() const { return &m_container[m_index]; } + constexpr ValueType* operator->() { return &m_container[m_index]; } + +private: + static constexpr SimpleIterator begin(Container& container) { return { container, 0 }; } + static constexpr SimpleIterator end(Container& container) + { + using RawContainerType = typename RemoveCV::Type; + + if constexpr (IsSame::value || IsSame::value) + return { container, container.length() }; + else + return { container, container.size() }; + } + + constexpr SimpleIterator(Container& container, size_t index) + : m_container(container) + , m_index(index) + { + } + + Container& m_container; + size_t m_index; +}; + +} diff --git a/AK/NonnullPtrVector.h b/AK/NonnullPtrVector.h index 61772b4ddca..3698015974f 100644 --- a/AK/NonnullPtrVector.h +++ b/AK/NonnullPtrVector.h @@ -51,13 +51,14 @@ public: using Base::size; - using Iterator = VectorIterator; - Iterator begin() { return Iterator(*this, 0); } - Iterator end() { return Iterator(*this, size()); } + using ConstIterator = SimpleIterator; + using Iterator = SimpleIterator; - using ConstIterator = VectorIterator; - ConstIterator begin() const { return ConstIterator(*this, 0); } - ConstIterator end() const { return ConstIterator(*this, size()); } + constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } + constexpr Iterator begin() { return Iterator::begin(*this); } + + constexpr ConstIterator end() const { return ConstIterator::end(*this); } + constexpr Iterator end() { return Iterator::end(*this); } PtrType& ptr_at(int index) { return Base::at(index); } const PtrType& ptr_at(int index) const { return Base::at(index); } diff --git a/AK/Span.h b/AK/Span.h index a0084d63403..216ad889812 100644 --- a/AK/Span.h +++ b/AK/Span.h @@ -28,6 +28,7 @@ #include #include +#include #include namespace AK { @@ -102,9 +103,6 @@ protected: template class Span : public Detail::Span { public: - using Iterator = T*; - using ConstIterator = const T*; - using Detail::Span::Span; ALWAYS_INLINE Span(std::nullptr_t) @@ -120,23 +118,14 @@ public: ALWAYS_INLINE const T* data() const { return this->m_values; } ALWAYS_INLINE T* data() { return this->m_values; } - ALWAYS_INLINE ConstIterator begin() const - { - return this->m_values; - } - ALWAYS_INLINE ConstIterator end() const - { - return begin() + size(); - } + using ConstIterator = SimpleIterator; + using Iterator = SimpleIterator; - ALWAYS_INLINE Iterator begin() - { - return this->m_values; - } - ALWAYS_INLINE Iterator end() - { - return begin() + size(); - } + constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } + constexpr Iterator begin() { return Iterator::begin(*this); } + + constexpr ConstIterator end() const { return ConstIterator::end(*this); } + constexpr Iterator end() { return Iterator::end(*this); } ALWAYS_INLINE size_t size() const { return this->m_size; } @@ -220,6 +209,7 @@ public: using ReadonlyBytes = Span; using Bytes = Span; + } using AK::Bytes; diff --git a/AK/String.h b/AK/String.h index 4e7b84f72f8..f4470fe98b1 100644 --- a/AK/String.h +++ b/AK/String.h @@ -58,8 +58,6 @@ namespace AK { class String { public: - using ConstIterator = const char*; - ~String() { } String() { } @@ -155,8 +153,10 @@ public: return (*m_impl)[i]; } - ConstIterator begin() const { return characters(); } - ConstIterator end() const { return begin() + length(); } + using ConstIterator = SimpleIterator; + + constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } + constexpr ConstIterator end() const { return ConstIterator::end(*this); } bool starts_with(const StringView&, CaseSensitivity = CaseSensitivity::CaseSensitive) const; bool ends_with(const StringView&, CaseSensitivity = CaseSensitivity::CaseSensitive) const; diff --git a/AK/StringView.h b/AK/StringView.h index a1d4de9cbb7..9a03fd9bc89 100644 --- a/AK/StringView.h +++ b/AK/StringView.h @@ -37,8 +37,6 @@ namespace AK { class StringView { public: - using ConstIterator = const char*; - ALWAYS_INLINE constexpr StringView() { } ALWAYS_INLINE constexpr StringView(const char* characters, size_t length) : m_characters(characters) @@ -77,8 +75,10 @@ public: const char& operator[](size_t index) const { return m_characters[index]; } - ConstIterator begin() const { return characters_without_null_termination(); } - ConstIterator end() const { return begin() + length(); } + using ConstIterator = SimpleIterator; + + constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } + constexpr ConstIterator end() const { return ConstIterator::end(*this); } unsigned hash() const; diff --git a/AK/Vector.h b/AK/Vector.h index f30fbdbd4b5..c65f1753a10 100644 --- a/AK/Vector.h +++ b/AK/Vector.h @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -47,49 +48,6 @@ namespace AK { -template -class VectorIterator { -public: - bool operator!=(const VectorIterator& other) const { return m_index != other.m_index; } - bool operator==(const VectorIterator& other) const { return m_index == other.m_index; } - bool operator<(const VectorIterator& other) const { return m_index < other.m_index; } - bool operator>(const VectorIterator& other) const { return m_index > other.m_index; } - bool operator>=(const VectorIterator& other) const { return m_index >= other.m_index; } - ALWAYS_INLINE VectorIterator& operator++() - { - ++m_index; - return *this; - } - VectorIterator& operator--() - { - --m_index; - return *this; - } - VectorIterator operator-(size_t value) { return { m_vector, m_index - value }; } - VectorIterator operator+(size_t value) { return { m_vector, m_index + value }; } - VectorIterator& operator=(const VectorIterator& other) - { - m_index = other.m_index; - return *this; - } - ALWAYS_INLINE ElementType& operator*() { return m_vector[m_index]; } - ALWAYS_INLINE ElementType* operator->() { return &m_vector[m_index]; } - size_t operator-(const VectorIterator& other) { return m_index - other.m_index; } - - bool is_end() const { return m_index == m_vector.size(); } - size_t index() const { return m_index; } - -private: - friend VectorType; - VectorIterator(VectorType& vector, size_t index) - : m_vector(vector) - , m_index(index) - { - } - VectorType& m_vector; - size_t m_index { 0 }; -}; - template class TypedTransfer { public: @@ -582,13 +540,14 @@ public: return resize(new_size, true); } - using Iterator = VectorIterator; - Iterator begin() { return Iterator(*this, 0); } - Iterator end() { return Iterator(*this, size()); } + using ConstIterator = SimpleIterator; + using Iterator = SimpleIterator; - using ConstIterator = VectorIterator; - ConstIterator begin() const { return ConstIterator(*this, 0); } - ConstIterator end() const { return ConstIterator(*this, size()); } + ConstIterator begin() const { return ConstIterator::begin(*this); } + Iterator begin() { return Iterator::begin(*this); } + + ConstIterator end() const { return ConstIterator::end(*this); } + Iterator end() { return Iterator::end(*this); } template ConstIterator find(Finder finder) const @@ -605,7 +564,7 @@ public: { for (size_t i = 0; i < m_size; ++i) { if (finder(at(i))) - return Iterator(*this, i); + return Iterator { *this, i }; } return end(); }