Skip to content

Commit

Permalink
AK: Add generic SimpleIterator class to replace VectorIterator.
Browse files Browse the repository at this point in the history
  • Loading branch information
asynts authored and awesomekling committed Sep 8, 2020
1 parent 9648bf4 commit 1b3ecb0
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 90 deletions.
16 changes: 9 additions & 7 deletions AK/FixedArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@

#pragma once

#include <AK/Iterator.h>
#include <AK/Span.h>
#include <AK/Vector.h>
#include <AK/kmalloc.h>

namespace AK {

Expand Down Expand Up @@ -142,13 +143,14 @@ class FixedArray {
::swap(m_size, other.m_size);
}

using Iterator = VectorIterator<FixedArray, T>;
Iterator begin() { return Iterator(*this, 0); }
Iterator end() { return Iterator(*this, size()); }
using ConstIterator = SimpleIterator<const FixedArray, const T>;
using Iterator = SimpleIterator<FixedArray, T>;

using ConstIterator = VectorIterator<const FixedArray, const T>;
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(); }
Expand Down
7 changes: 7 additions & 0 deletions AK/Forward.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ class CircularDuplexStream;
template<typename T>
class Span;

template<typename T>
class Array;

template<typename Container, typename ValueType>
class SimpleIterator;

using ReadonlyBytes = Span<const u8>;
using Bytes = Span<u8>;

Expand Down Expand Up @@ -123,6 +129,7 @@ class Vector;

}

using AK::Array;
using AK::Atomic;
using AK::Badge;
using AK::Bitmap;
Expand Down
103 changes: 103 additions & 0 deletions AK/Iterator.h
Original file line number Diff line number Diff line change
@@ -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 <AK/Forward.h>

namespace AK {

template<typename Container, typename ValueType>
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<ptrdiff_t>(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<Container>::Type;

if constexpr (IsSame<StringView, RawContainerType>::value || IsSame<String, RawContainerType>::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;
};

}
13 changes: 7 additions & 6 deletions AK/NonnullPtrVector.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,14 @@ class NonnullPtrVector : public Vector<PtrType, inline_capacity> {

using Base::size;

using Iterator = VectorIterator<NonnullPtrVector, T>;
Iterator begin() { return Iterator(*this, 0); }
Iterator end() { return Iterator(*this, size()); }
using ConstIterator = SimpleIterator<const NonnullPtrVector, const T>;
using Iterator = SimpleIterator<NonnullPtrVector, T>;

using ConstIterator = VectorIterator<const NonnullPtrVector, const T>;
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); }
Expand Down
28 changes: 9 additions & 19 deletions AK/Span.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <AK/Assertions.h>
#include <AK/Checked.h>
#include <AK/Iterator.h>
#include <AK/Types.h>

namespace AK {
Expand Down Expand Up @@ -102,9 +103,6 @@ class Span<const u8> {
template<typename T>
class Span : public Detail::Span<T> {
public:
using Iterator = T*;
using ConstIterator = const T*;

using Detail::Span<T>::Span;

ALWAYS_INLINE Span(std::nullptr_t)
Expand All @@ -120,23 +118,14 @@ class Span : public Detail::Span<T> {
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<const Span, const T>;
using Iterator = SimpleIterator<Span, T>;

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; }

Expand Down Expand Up @@ -220,6 +209,7 @@ class Span : public Detail::Span<T> {

using ReadonlyBytes = Span<const u8>;
using Bytes = Span<u8>;

}

using AK::Bytes;
Expand Down
8 changes: 4 additions & 4 deletions AK/String.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ namespace AK {

class String {
public:
using ConstIterator = const char*;

~String() { }

String() { }
Expand Down Expand Up @@ -155,8 +153,10 @@ class String {
return (*m_impl)[i];
}

ConstIterator begin() const { return characters(); }
ConstIterator end() const { return begin() + length(); }
using ConstIterator = SimpleIterator<const String, const char>;

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;
Expand Down
8 changes: 4 additions & 4 deletions AK/StringView.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -77,8 +75,10 @@ class StringView {

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<const StringView, const char>;

constexpr ConstIterator begin() const { return ConstIterator::begin(*this); }
constexpr ConstIterator end() const { return ConstIterator::end(*this); }

unsigned hash() const;

Expand Down
59 changes: 9 additions & 50 deletions AK/Vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <AK/Assertions.h>
#include <AK/Forward.h>
#include <AK/Iterator.h>
#include <AK/Optional.h>
#include <AK/Span.h>
#include <AK/StdLibExtras.h>
Expand All @@ -47,49 +48,6 @@

namespace AK {

template<typename VectorType, typename ElementType>
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<typename T>
class TypedTransfer {
public:
Expand Down Expand Up @@ -582,13 +540,14 @@ class Vector {
return resize(new_size, true);
}

using Iterator = VectorIterator<Vector, T>;
Iterator begin() { return Iterator(*this, 0); }
Iterator end() { return Iterator(*this, size()); }
using ConstIterator = SimpleIterator<const Vector, const T>;
using Iterator = SimpleIterator<Vector, T>;

ConstIterator begin() const { return ConstIterator::begin(*this); }
Iterator begin() { return Iterator::begin(*this); }

using ConstIterator = VectorIterator<const Vector, const T>;
ConstIterator begin() const { return ConstIterator(*this, 0); }
ConstIterator end() const { return ConstIterator(*this, size()); }
ConstIterator end() const { return ConstIterator::end(*this); }
Iterator end() { return Iterator::end(*this); }

template<typename Finder>
ConstIterator find(Finder finder) const
Expand All @@ -605,7 +564,7 @@ class Vector {
{
for (size_t i = 0; i < m_size; ++i) {
if (finder(at(i)))
return Iterator(*this, i);
return Iterator { *this, i };
}
return end();
}
Expand Down

0 comments on commit 1b3ecb0

Please sign in to comment.