serenity/AK/Iterator.h
Ali Mohammad Pur 3d94b5051d AK: Make Vector capable of holding reference types
This commit makes it possible to instantiate `Vector<T&>` and use it
to store references to `T` in a vector.
All non-pointer observers are made to return the reference, and the
pointer observers simply yield the underlying pointer.
Note that the 'find_*' methods act on the values and not the pointers
that are stored in the vector.
This commit also makes errors in various vector methods much more
readable by directly using requires-clauses on them.
And finally, it should be noted that Vector cannot hold temporaries :^)
2021-06-08 19:14:24 +02:00

90 lines
2.9 KiB
C++

/*
* Copyright (c) 2020, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#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 };
}
ALWAYS_INLINE constexpr const ValueType& operator*() const { return m_container[m_index]; }
ALWAYS_INLINE constexpr ValueType& operator*() { return m_container[m_index]; }
constexpr auto operator->() const { return &m_container[m_index]; }
constexpr auto operator->() { return &m_container[m_index]; }
SimpleIterator& operator=(const SimpleIterator& other)
{
m_index = other.m_index;
return *this;
}
SimpleIterator(const SimpleIterator& obj) = default;
private:
static constexpr SimpleIterator begin(Container& container) { return { container, 0 }; }
static constexpr SimpleIterator end(Container& container)
{
using RawContainerType = RemoveCV<Container>;
if constexpr (IsSame<StringView, RawContainerType> || IsSame<String, RawContainerType>)
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;
};
}