Coverage Report

Created: 2025-03-04 07:22

/src/serenity/Userland/Libraries/LibJS/Runtime/Map.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#pragma once
8
9
#include <AK/HashMap.h>
10
#include <AK/RedBlackTree.h>
11
#include <LibJS/Runtime/GlobalObject.h>
12
#include <LibJS/Runtime/Object.h>
13
#include <LibJS/Runtime/Value.h>
14
#include <LibJS/Runtime/ValueTraits.h>
15
16
namespace JS {
17
18
class Map : public Object {
19
    JS_OBJECT(Map, Object);
20
    JS_DECLARE_ALLOCATOR(Map);
21
22
public:
23
    static NonnullGCPtr<Map> create(Realm&);
24
25
0
    virtual ~Map() override = default;
26
27
    void map_clear();
28
    bool map_remove(Value const&);
29
    Optional<Value> map_get(Value const&) const;
30
    bool map_has(Value const&) const;
31
    void map_set(Value const&, Value);
32
    size_t map_size() const;
33
34
    struct EndIterator {
35
    };
36
37
    template<bool IsConst>
38
    struct IteratorImpl {
39
        bool is_end() const
40
0
        {
41
0
            return m_map->m_keys.begin_from(m_index).is_end()
42
0
                && m_map->m_keys.find_smallest_not_below_iterator(m_index).is_end();
43
0
        }
Unexecuted instantiation: JS::Map::IteratorImpl<true>::is_end() const
Unexecuted instantiation: JS::Map::IteratorImpl<false>::is_end() const
44
45
        IteratorImpl& operator++()
46
0
        {
47
0
            ++m_index;
48
0
            return *this;
49
0
        }
Unexecuted instantiation: JS::Map::IteratorImpl<true>::operator++()
Unexecuted instantiation: JS::Map::IteratorImpl<false>::operator++()
50
51
        decltype(auto) operator*()
52
0
        {
53
0
            ensure_next_element();
54
0
            return *m_map->m_entries.find(*m_map->m_keys.begin_from(m_index));
55
0
        }
Unexecuted instantiation: JS::Map::IteratorImpl<true>::operator*()
Unexecuted instantiation: JS::Map::IteratorImpl<false>::operator*()
56
57
        decltype(auto) operator*() const
58
        {
59
            ensure_next_element();
60
            return *m_map->m_entries.find(*m_map->m_keys.begin_from(m_index));
61
        }
62
63
        bool operator==(IteratorImpl const& other) const { return m_index == other.m_index && &m_map == &other.m_map; }
64
0
        bool operator==(EndIterator const&) const { return is_end(); }
Unexecuted instantiation: JS::Map::IteratorImpl<true>::operator==(JS::Map::EndIterator const&) const
Unexecuted instantiation: JS::Map::IteratorImpl<false>::operator==(JS::Map::EndIterator const&) const
65
66
    private:
67
        friend class Map;
68
        IteratorImpl(Map const& map)
69
        requires(IsConst)
70
0
            : m_map(map)
71
0
        {
72
0
            ensure_index();
73
0
        }
74
75
        IteratorImpl(Map& map)
76
        requires(!IsConst)
77
0
            : m_map(map)
78
0
        {
79
0
            ensure_index();
80
0
        }
81
82
        void ensure_index() const
83
0
        {
84
0
            if (m_map->m_keys.is_empty())
85
0
                m_index = m_map->m_next_insertion_id;
86
0
            else
87
0
                m_index = m_map->m_keys.begin().key();
88
0
        }
Unexecuted instantiation: JS::Map::IteratorImpl<true>::ensure_index() const
Unexecuted instantiation: JS::Map::IteratorImpl<false>::ensure_index() const
89
90
        void ensure_next_element() const
91
0
        {
92
0
            if (auto it = m_map->m_keys.find_smallest_not_below_iterator(m_index); it.is_end())
93
0
                m_index = m_map->m_next_insertion_id;
94
0
            else
95
0
                m_index = it.key();
96
0
        }
Unexecuted instantiation: JS::Map::IteratorImpl<true>::ensure_next_element() const
Unexecuted instantiation: JS::Map::IteratorImpl<false>::ensure_next_element() const
97
98
        Conditional<IsConst, NonnullGCPtr<Map const>, NonnullGCPtr<Map>> m_map;
99
        mutable size_t m_index { 0 };
100
    };
101
102
    using Iterator = IteratorImpl<false>;
103
    using ConstIterator = IteratorImpl<true>;
104
105
0
    ConstIterator begin() const { return { *this }; }
106
0
    Iterator begin() { return { *this }; }
107
0
    EndIterator end() const { return {}; }
108
109
private:
110
    explicit Map(Object& prototype);
111
    virtual void visit_edges(Visitor& visitor) override;
112
113
    size_t m_next_insertion_id { 0 };
114
    RedBlackTree<size_t, Value> m_keys;
115
    HashMap<Value, Value, ValueTraits> m_entries;
116
};
117
118
}