/* * Copyright (c) 2021, Brian Gianforcaro * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include namespace AK { template class SinglyLinkedListWithCount : private SinglyLinkedList { public: SinglyLinkedListWithCount() = default; ~SinglyLinkedListWithCount() = default; using List = SinglyLinkedList; using List::is_empty; using List::size_slow; inline size_t size() const { return m_count; } void clear() { List::clear(); m_count = 0; } T& first() { return List::first(); } const T& first() const { return List::first(); } T& last() { return List::last(); } const T& last() const { return List::last(); } T take_first() { m_count--; return List::take_first(); } template ErrorOr try_append(U&& value) { auto result = List::try_append(forward(value)); if (!result.is_error()) m_count++; return result; } #ifndef KERNEL template void append(U&& value) { MUST(try_append(forward(value))); } #endif bool contains_slow(const T& value) const { return List::contains_slow(value); } using Iterator = typename List::Iterator; friend Iterator; Iterator begin() { return List::begin(); } Iterator end() { return List::end(); } using ConstIterator = typename List::ConstIterator; friend ConstIterator; ConstIterator begin() const { return List::begin(); } ConstIterator end() const { return List::end(); } template ConstIterator find(TUnaryPredicate&& pred) const { return List::find_if(forward(pred)); } template Iterator find(TUnaryPredicate&& pred) { return List::find_if(forward(pred)); } ConstIterator find(const T& value) const { return List::find(value); } Iterator find(const T& value) { return List::find(value); } void remove(Iterator iterator) { m_count--; return List::remove(iterator); } template void insert_before(Iterator iterator, U&& value) { m_count++; List::insert_before(iterator, forward(value)); } template void insert_after(Iterator iterator, U&& value) { m_count++; List::insert_after(iterator, forward(value)); } private: size_t m_count { 0 }; }; } #if USING_AK_GLOBALLY using AK::SinglyLinkedListWithCount; #endif