summaryrefslogtreecommitdiff
path: root/AK/SinglyLinkedListWithCount.h
blob: 4f47ef7a2414099ae93498026025b8a430711d6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * Copyright (c) 2021, Brian Gianforcaro <bgianf@serenityos.org>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <AK/SinglyLinkedList.h>

namespace AK {

template<typename T>
class SinglyLinkedListWithCount : private SinglyLinkedList<T> {

public:
    SinglyLinkedListWithCount() = default;
    ~SinglyLinkedListWithCount() = default;

    using List = SinglyLinkedList<T>;

    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<typename U = T>
    void append(U&& value)
    {
        m_count++;
        return List::append(forward<T>(value));
    }

    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<typename TUnaryPredicate>
    ConstIterator find(TUnaryPredicate&& pred) const
    {
        return List::find_if(forward<TUnaryPredicate>(pred));
    }

    template<typename TUnaryPredicate>
    Iterator find(TUnaryPredicate&& pred)
    {
        return List::find_if(forward<TUnaryPredicate>(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<typename U = T>
    void insert_before(Iterator iterator, U&& value)
    {
        m_count++;
        List::insert_before(iterator, forward<T>(value));
    }

    template<typename U = T>
    void insert_after(Iterator iterator, U&& value)
    {
        m_count++;
        List::insert_after(iterator, forward<T>(value));
    }

private:
    size_t m_count { 0 };
};

}

using AK::SinglyLinkedListWithCount;