forked from Bananymous/banan-os
BAN: Implement ConstIteratorDouble and add it to HashMap
This is same as IteratorDouble except it uses const_iterator and does not return non-const references.
This commit is contained in:
parent
4285729d5c
commit
6b0920e8c0
|
@ -31,6 +31,7 @@ namespace BAN
|
||||||
using key_type = Key;
|
using key_type = Key;
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
using iterator = IteratorDouble<Entry, Vector, LinkedList, HashMap>;
|
using iterator = IteratorDouble<Entry, Vector, LinkedList, HashMap>;
|
||||||
|
using const_iterator = ConstIteratorDouble<Entry, Vector, LinkedList, HashMap>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HashMap() = default;
|
HashMap() = default;
|
||||||
|
@ -48,6 +49,8 @@ namespace BAN
|
||||||
|
|
||||||
iterator begin() { return iterator(m_buckets.end(), m_buckets.begin()); }
|
iterator begin() { return iterator(m_buckets.end(), m_buckets.begin()); }
|
||||||
iterator end() { return iterator(m_buckets.end(), m_buckets.end()); }
|
iterator end() { return iterator(m_buckets.end(), m_buckets.end()); }
|
||||||
|
const_iterator begin() const { return const_iterator(m_buckets.end(), m_buckets.begin()); }
|
||||||
|
const_iterator end() const { return const_iterator(m_buckets.end(), m_buckets.end()); }
|
||||||
|
|
||||||
ErrorOr<void> reserve(size_type);
|
ErrorOr<void> reserve(size_type);
|
||||||
|
|
||||||
|
|
|
@ -266,4 +266,105 @@ namespace BAN
|
||||||
friend Container;
|
friend Container;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T, template <typename> typename OuterContainer, template <typename> typename InnerContainer, typename Container>
|
||||||
|
class ConstIteratorDouble
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Inner = InnerContainer<T>;
|
||||||
|
using Outer = OuterContainer<Inner>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ConstIteratorDouble() = default;
|
||||||
|
ConstIteratorDouble(const IteratorDouble<T, OuterContainer, InnerContainer, Container>& other)
|
||||||
|
: m_outer_end(other.m_outer_end)
|
||||||
|
, m_outer_current(other.m_outer_current)
|
||||||
|
, m_inner_current(other.m_inner_current)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator*() const
|
||||||
|
{
|
||||||
|
ASSERT(*this);
|
||||||
|
ASSERT(m_outer_current != m_outer_end);
|
||||||
|
ASSERT(m_inner_current);
|
||||||
|
return m_inner_current.operator*();
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* operator->() const
|
||||||
|
{
|
||||||
|
ASSERT(*this);
|
||||||
|
ASSERT(m_outer_current != m_outer_end);
|
||||||
|
ASSERT(m_inner_current);
|
||||||
|
return m_inner_current.operator->();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstIteratorDouble& operator++()
|
||||||
|
{
|
||||||
|
ASSERT(*this);
|
||||||
|
ASSERT(m_outer_current != m_outer_end);
|
||||||
|
ASSERT(m_inner_current);
|
||||||
|
m_inner_current++;
|
||||||
|
find_valid_or_end();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
ConstIteratorDouble operator++(int)
|
||||||
|
{
|
||||||
|
auto temp = *this;
|
||||||
|
++(*this);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const ConstIteratorDouble& other) const
|
||||||
|
{
|
||||||
|
if (!*this || !other)
|
||||||
|
return false;
|
||||||
|
if (m_outer_end != other.m_outer_end)
|
||||||
|
return false;
|
||||||
|
if (m_outer_current != other.m_outer_current)
|
||||||
|
return false;
|
||||||
|
if (m_outer_current == m_outer_end)
|
||||||
|
return true;
|
||||||
|
return m_inner_current == other.m_inner_current;
|
||||||
|
}
|
||||||
|
bool operator!=(const ConstIteratorDouble& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
return m_outer_end && m_outer_current;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConstIteratorDouble(Outer::const_iterator outer_end, Outer::const_iterator outer_current)
|
||||||
|
: m_outer_end(outer_end)
|
||||||
|
, m_outer_current(outer_current)
|
||||||
|
{
|
||||||
|
if (outer_current != outer_end)
|
||||||
|
{
|
||||||
|
m_inner_current = m_outer_current->begin();
|
||||||
|
find_valid_or_end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void find_valid_or_end()
|
||||||
|
{
|
||||||
|
while (m_inner_current == m_outer_current->end())
|
||||||
|
{
|
||||||
|
m_outer_current++;
|
||||||
|
if (m_outer_current == m_outer_end)
|
||||||
|
break;
|
||||||
|
m_inner_current = m_outer_current->begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Outer::const_iterator m_outer_end;
|
||||||
|
Outer::const_iterator m_outer_current;
|
||||||
|
Inner::const_iterator m_inner_current;
|
||||||
|
|
||||||
|
friend Container;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue