Coverage Report

Created: 2023-06-07 06:37

/src/immer/immer/detail/hamts/champ.hpp
Line
Count
Source (jump to first uncovered line)
1
//
2
// immer: immutable data structures for C++
3
// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente
4
//
5
// This software is distributed under the Boost Software License, Version 1.0.
6
// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt
7
//
8
9
#pragma once
10
11
#include <immer/config.hpp>
12
#include <immer/detail/hamts/node.hpp>
13
14
#include <algorithm>
15
16
namespace immer {
17
namespace detail {
18
namespace hamts {
19
20
#if IMMER_DEBUG_STATS
21
struct champ_debug_stats
22
{
23
    std::size_t bits       = {};
24
    std::size_t value_size = {};
25
    std::size_t child_size = sizeof(void*);
26
27
    std::size_t inner_node_count         = {};
28
    std::size_t inner_node_w_value_count = {};
29
    std::size_t inner_node_w_child_count = {};
30
    std::size_t collision_node_count     = {};
31
32
    std::size_t child_count     = {};
33
    std::size_t value_count     = {};
34
    std::size_t collision_count = {};
35
36
    friend champ_debug_stats operator+(champ_debug_stats a, champ_debug_stats b)
37
    {
38
        if (a.bits != b.bits || a.value_size != b.value_size ||
39
            a.child_size != b.child_size)
40
            throw std::runtime_error{"accumulating incompatible stats"};
41
        return {
42
            a.bits,
43
            a.value_size,
44
            a.child_size,
45
            a.inner_node_count + b.inner_node_count,
46
            a.inner_node_w_value_count + b.inner_node_w_value_count,
47
            a.inner_node_w_child_count + b.inner_node_w_child_count,
48
            a.collision_node_count + b.collision_node_count,
49
            a.child_count + b.child_count,
50
            a.value_count + b.value_count,
51
            a.collision_count + b.collision_count,
52
        };
53
    }
54
55
    struct summary
56
    {
57
        double collision_ratio;
58
59
        double utilization;
60
        double child_utilization;
61
        double value_utilization;
62
63
        double dense_utilization;
64
        double dense_value_utilization;
65
        double dense_child_utilization;
66
67
        friend std::ostream& operator<<(std::ostream& os, const summary& s)
68
        {
69
            os << "---\n";
70
            os << "collisions\n"
71
               << "  ratio = " << s.collision_ratio << " %\n";
72
            os << "utilization\n"
73
               << "  total    = " << s.utilization << " %\n"
74
               << "  children = " << s.child_utilization << " %\n"
75
               << "  values   = " << s.value_utilization << " %\n";
76
            os << "utilization (dense)\n"
77
               << "  total    = " << s.dense_utilization << " %\n"
78
               << "  children = " << s.dense_child_utilization << " %\n"
79
               << "  values   = " << s.dense_value_utilization << " %\n";
80
            return os;
81
        }
82
    };
83
84
    summary get_summary() const
85
    {
86
        auto m = std::size_t{1} << bits;
87
88
        auto collision_ratio = 100. * collision_count / value_count;
89
90
        auto capacity          = m * inner_node_count;
91
        auto child_utilization = 100. * child_count / capacity;
92
        auto value_utilization = 100. * value_count / capacity;
93
        auto utilization =
94
            100. * (value_count * value_size + child_count * child_size) /
95
            (capacity * value_size + capacity * child_size);
96
97
        auto value_capacity = m * inner_node_w_value_count;
98
        auto child_capacity = m * inner_node_w_child_count;
99
        auto dense_child_utilization =
100
            child_capacity == 0 ? 100. : 100. * child_count / child_capacity;
101
        auto dense_value_utilization =
102
            value_capacity == 0 ? 100. : 100. * value_count / value_capacity;
103
        auto dense_utilization =
104
            value_capacity + child_capacity == 0
105
                ? 100.
106
                : 100. * (value_count * value_size + child_count * child_size) /
107
                      (value_capacity * value_size +
108
                       child_capacity * child_size);
109
110
        return {collision_ratio,
111
                utilization,
112
                child_utilization,
113
                value_utilization,
114
                dense_utilization,
115
                dense_value_utilization,
116
                dense_child_utilization};
117
    }
118
};
119
#endif
120
121
template <typename T,
122
          typename Hash,
123
          typename Equal,
124
          typename MemoryPolicy,
125
          bits_t B>
126
struct champ
127
{
128
    static constexpr auto bits = B;
129
130
    using node_t   = node<T, Hash, Equal, MemoryPolicy, B>;
131
    using edit_t   = typename MemoryPolicy::transience_t::edit;
132
    using owner_t  = typename MemoryPolicy::transience_t::owner;
133
    using bitmap_t = typename get_bitmap_type<B>::type;
134
135
    static_assert(branches<B> <= sizeof(bitmap_t) * 8, "");
136
137
    node_t* root;
138
    size_t size;
139
140
    static node_t* empty()
141
940k
    {
142
940k
        static const auto node = node_t::make_inner_n(0);
143
940k
        return node->inc();
144
940k
    }
145
146
    champ(node_t* r, size_t sz = 0)
147
        : root{r}
148
        , size{sz}
149
1.87M
    {}
150
151
    champ(const champ& other)
152
        : champ{other.root, other.size}
153
27.7k
    {
154
27.7k
        inc();
155
27.7k
    }
156
157
    champ(champ&& other)
158
        : champ{empty()}
159
924k
    {
160
924k
        swap(*this, other);
161
924k
    }
162
163
    champ& operator=(const champ& other)
164
    {
165
        auto next = other;
166
        swap(*this, next);
167
        return *this;
168
    }
169
170
    champ& operator=(champ&& other)
171
1.03M
    {
172
1.03M
        swap(*this, other);
173
1.03M
        return *this;
174
1.03M
    }
175
176
    friend void swap(champ& x, champ& y)
177
1.96M
    {
178
1.96M
        using std::swap;
179
1.96M
        swap(x.root, y.root);
180
1.96M
        swap(x.size, y.size);
181
1.96M
    }
182
183
1.87M
    ~champ() { dec(); }
184
185
27.7k
    void inc() const { root->inc(); }
186
187
    void dec() const
188
1.87M
    {
189
1.87M
        if (root->dec())
190
918k
            node_t::delete_deep(root, 0);
191
1.87M
    }
192
193
    std::size_t do_check_champ(node_t* node,
194
                               count_t depth,
195
                               size_t path_hash,
196
                               size_t hash_mask) const
197
17.2M
    {
198
17.2M
        auto result = std::size_t{};
199
17.2M
        if (depth < max_depth<B>) {
200
17.1M
            auto nodemap = node->nodemap();
201
17.1M
            if (nodemap) {
202
11.4M
                auto fst = node->children();
203
102M
                for (auto idx = std::size_t{}; idx < branches<B>; ++idx) {
204
91.4M
                    if (nodemap & (1 << idx)) {
205
16.8M
                        auto child = *fst++;
206
16.8M
                        result +=
207
16.8M
                            do_check_champ(child,
208
16.8M
                                           depth + 1,
209
16.8M
                                           path_hash | (idx << (B * depth)),
210
16.8M
                                           (hash_mask << B) | mask<B>);
211
16.8M
                    }
212
91.4M
                }
213
11.4M
            }
214
17.1M
            auto datamap = node->datamap();
215
17.1M
            if (datamap) {
216
8.73M
                auto fst = node->values();
217
78.5M
                for (auto idx = std::size_t{}; idx < branches<B>; ++idx) {
218
69.8M
                    if (datamap & (1 << idx)) {
219
20.6M
                        auto hash  = Hash{}(*fst++);
220
20.6M
                        auto check = (hash & hash_mask) ==
221
20.6M
                                     (path_hash | (idx << (B * depth)));
222
                        // assert(check);
223
20.6M
                        result += !!check;
224
20.6M
                    }
225
69.8M
                }
226
8.73M
            }
227
17.1M
        } else {
228
158k
            auto fst = node->collisions();
229
158k
            auto lst = fst + node->collision_count();
230
516k
            for (; fst != lst; ++fst) {
231
357k
                auto hash  = Hash{}(*fst);
232
357k
                auto check = hash == path_hash;
233
                // assert(check);
234
357k
                result += !!check;
235
357k
            }
236
158k
        }
237
17.2M
        return result;
238
17.2M
    }
239
240
    // Checks that the hashes of the values correspond with what has actually
241
    // been inserted.  If it doesn't it can mean that corruption has happened
242
    // due some value being moved out of the champ when it should have not.
243
    bool check_champ() const
244
467k
    {
245
467k
        auto r = do_check_champ(root, 0, 0, mask<B>);
246
        // assert(r == size);
247
467k
        return r == size;
248
467k
    }
249
250
#if IMMER_DEBUG_STATS
251
    void do_get_debug_stats(champ_debug_stats& stats,
252
                            node_t* node,
253
                            count_t depth) const
254
    {
255
        if (depth < max_depth<B>) {
256
            ++stats.inner_node_count;
257
            stats.inner_node_w_value_count += node->data_count() > 0;
258
            stats.inner_node_w_child_count += node->children_count() > 0;
259
            stats.value_count += node->data_count();
260
            stats.child_count += node->children_count();
261
            auto nodemap = node->nodemap();
262
            if (nodemap) {
263
                auto fst = node->children();
264
                auto lst = fst + node->children_count();
265
                for (; fst != lst; ++fst)
266
                    do_get_debug_stats(stats, *fst, depth + 1);
267
            }
268
        } else {
269
            ++stats.collision_node_count;
270
            stats.collision_count += node->collision_count();
271
        }
272
    }
273
274
    champ_debug_stats get_debug_stats() const
275
    {
276
        auto stats = champ_debug_stats{B, sizeof(T)};
277
        do_get_debug_stats(stats, root, 0);
278
        return stats;
279
    }
280
#endif
281
282
    template <typename U>
283
    static auto from_initializer_list(std::initializer_list<U> values)
284
    {
285
        auto e      = owner_t{};
286
        auto result = champ{empty()};
287
        for (auto&& v : values)
288
            result.add_mut(e, v);
289
        return result;
290
    }
291
292
    template <typename Iter,
293
              typename Sent,
294
              std::enable_if_t<compatible_sentinel_v<Iter, Sent>, bool> = true>
295
    static auto from_range(Iter first, Sent last)
296
    {
297
        auto e      = owner_t{};
298
        auto result = champ{empty()};
299
        for (; first != last; ++first)
300
            result.add_mut(e, *first);
301
        return result;
302
    }
303
304
    template <typename Fn>
305
    void for_each_chunk(Fn&& fn) const
306
    {
307
        for_each_chunk_traversal(root, 0, fn);
308
    }
309
310
    template <typename Fn>
311
    void
312
    for_each_chunk_traversal(const node_t* node, count_t depth, Fn&& fn) const
313
285k
    {
314
285k
        if (depth < max_depth<B>) {
315
278k
            auto datamap = node->datamap();
316
278k
            if (datamap)
317
143k
                fn(node->values(), node->values() + node->data_count());
318
278k
            auto nodemap = node->nodemap();
319
278k
            if (nodemap) {
320
153k
                auto fst = node->children();
321
153k
                auto lst = fst + node->children_count();
322
317k
                for (; fst != lst; ++fst)
323
163k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
153k
            }
325
278k
        } else {
326
7.14k
            fn(node->collisions(),
327
7.14k
               node->collisions() + node->collision_count());
328
7.14k
        }
329
285k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
1.00k
    {
314
1.00k
        if (depth < max_depth<B>) {
315
1.00k
            auto datamap = node->datamap();
316
1.00k
            if (datamap)
317
0
                fn(node->values(), node->values() + node->data_count());
318
1.00k
            auto nodemap = node->nodemap();
319
1.00k
            if (nodemap) {
320
1.00k
                auto fst = node->children();
321
1.00k
                auto lst = fst + node->children_count();
322
2.01k
                for (; fst != lst; ++fst)
323
1.00k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
1.00k
            }
325
1.00k
        } else {
326
0
            fn(node->collisions(),
327
0
               node->collisions() + node->collision_count());
328
0
        }
329
1.00k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
18.6k
    {
314
18.6k
        if (depth < max_depth<B>) {
315
18.2k
            auto datamap = node->datamap();
316
18.2k
            if (datamap)
317
1.37k
                fn(node->values(), node->values() + node->data_count());
318
18.2k
            auto nodemap = node->nodemap();
319
18.2k
            if (nodemap) {
320
17.1k
                auto fst = node->children();
321
17.1k
                auto lst = fst + node->children_count();
322
34.8k
                for (; fst != lst; ++fst)
323
17.6k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
17.1k
            }
325
18.2k
        } else {
326
415
            fn(node->collisions(),
327
415
               node->collisions() + node->collision_count());
328
415
        }
329
18.6k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
1.85k
    {
314
1.85k
        if (depth < max_depth<B>) {
315
1.85k
            auto datamap = node->datamap();
316
1.85k
            if (datamap)
317
0
                fn(node->values(), node->values() + node->data_count());
318
1.85k
            auto nodemap = node->nodemap();
319
1.85k
            if (nodemap) {
320
1.85k
                auto fst = node->children();
321
1.85k
                auto lst = fst + node->children_count();
322
3.71k
                for (; fst != lst; ++fst)
323
1.85k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
1.85k
            }
325
1.85k
        } else {
326
0
            fn(node->collisions(),
327
0
               node->collisions() + node->collision_count());
328
0
        }
329
1.85k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
36.9k
    {
314
36.9k
        if (depth < max_depth<B>) {
315
36.0k
            auto datamap = node->datamap();
316
36.0k
            if (datamap)
317
4.75k
                fn(node->values(), node->values() + node->data_count());
318
36.0k
            auto nodemap = node->nodemap();
319
36.0k
            if (nodemap) {
320
32.8k
                auto fst = node->children();
321
32.8k
                auto lst = fst + node->children_count();
322
67.9k
                for (; fst != lst; ++fst)
323
35.0k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
32.8k
            }
325
36.0k
        } else {
326
834
            fn(node->collisions(),
327
834
               node->collisions() + node->collision_count());
328
834
        }
329
36.9k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
18.2k
    {
314
18.2k
        if (depth < max_depth<B>) {
315
18.0k
            auto datamap = node->datamap();
316
18.0k
            if (datamap)
317
15.0k
                fn(node->values(), node->values() + node->data_count());
318
18.0k
            auto nodemap = node->nodemap();
319
18.0k
            if (nodemap) {
320
5.37k
                auto fst = node->children();
321
5.37k
                auto lst = fst + node->children_count();
322
11.3k
                for (; fst != lst; ++fst)
323
6.02k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
5.37k
            }
325
18.0k
        } else {
326
205
            fn(node->collisions(),
327
205
               node->collisions() + node->collision_count());
328
205
        }
329
18.2k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
10.1k
    {
314
10.1k
        if (depth < max_depth<B>) {
315
9.36k
            auto datamap = node->datamap();
316
9.36k
            if (datamap)
317
5.52k
                fn(node->values(), node->values() + node->data_count());
318
9.36k
            auto nodemap = node->nodemap();
319
9.36k
            if (nodemap) {
320
3.94k
                auto fst = node->children();
321
3.94k
                auto lst = fst + node->children_count();
322
8.07k
                for (; fst != lst; ++fst)
323
4.13k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
3.94k
            }
325
9.36k
        } else {
326
791
            fn(node->collisions(),
327
791
               node->collisions() + node->collision_count());
328
791
        }
329
10.1k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
18.3k
    {
314
18.3k
        if (depth < max_depth<B>) {
315
18.1k
            auto datamap = node->datamap();
316
18.1k
            if (datamap)
317
15.3k
                fn(node->values(), node->values() + node->data_count());
318
18.1k
            auto nodemap = node->nodemap();
319
18.1k
            if (nodemap) {
320
5.17k
                auto fst = node->children();
321
5.17k
                auto lst = fst + node->children_count();
322
11.2k
                for (; fst != lst; ++fst)
323
6.07k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
5.17k
            }
325
18.1k
        } else {
326
204
            fn(node->collisions(),
327
204
               node->collisions() + node->collision_count());
328
204
        }
329
18.3k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
10.3k
    {
314
10.3k
        if (depth < max_depth<B>) {
315
9.50k
            auto datamap = node->datamap();
316
9.50k
            if (datamap)
317
5.72k
                fn(node->values(), node->values() + node->data_count());
318
9.50k
            auto nodemap = node->nodemap();
319
9.50k
            if (nodemap) {
320
4.12k
                auto fst = node->children();
321
4.12k
                auto lst = fst + node->children_count();
322
8.43k
                for (; fst != lst; ++fst)
323
4.31k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
4.12k
            }
325
9.50k
        } else {
326
880
            fn(node->collisions(),
327
880
               node->collisions() + node->collision_count());
328
880
        }
329
10.3k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff_data_node<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned char, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
41.2k
    {
314
41.2k
        if (depth < max_depth<B>) {
315
40.9k
            auto datamap = node->datamap();
316
40.9k
            if (datamap)
317
33.8k
                fn(node->values(), node->values() + node->data_count());
318
40.9k
            auto nodemap = node->nodemap();
319
40.9k
            if (nodemap) {
320
11.6k
                auto fst = node->children();
321
11.6k
                auto lst = fst + node->children_count();
322
24.0k
                for (; fst != lst; ++fst)
323
12.4k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
11.6k
            }
325
40.9k
        } else {
326
282
            fn(node->collisions(),
327
282
               node->collisions() + node->collision_count());
328
282
        }
329
41.2k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff_data_node<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned char, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
44.8k
    {
314
44.8k
        if (depth < max_depth<B>) {
315
43.5k
            auto datamap = node->datamap();
316
43.5k
            if (datamap)
317
14.6k
                fn(node->values(), node->values() + node->data_count());
318
43.5k
            auto nodemap = node->nodemap();
319
43.5k
            if (nodemap) {
320
30.4k
                auto fst = node->children();
321
30.4k
                auto lst = fst + node->children_count();
322
62.7k
                for (; fst != lst; ++fst)
323
32.3k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
30.4k
            }
325
43.5k
        } else {
326
1.30k
            fn(node->collisions(),
327
1.30k
               node->collisions() + node->collision_count());
328
1.30k
        }
329
44.8k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff_node_data<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned char, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
41.0k
    {
314
41.0k
        if (depth < max_depth<B>) {
315
40.7k
            auto datamap = node->datamap();
316
40.7k
            if (datamap)
317
33.0k
                fn(node->values(), node->values() + node->data_count());
318
40.7k
            auto nodemap = node->nodemap();
319
40.7k
            if (nodemap) {
320
11.8k
                auto fst = node->children();
321
11.8k
                auto lst = fst + node->children_count();
322
24.9k
                for (; fst != lst; ++fst)
323
13.1k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
11.8k
            }
325
40.7k
        } else {
326
306
            fn(node->collisions(),
327
306
               node->collisions() + node->collision_count());
328
306
        }
329
41.0k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::for_each_chunk_traversal<immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff_node_data<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned char, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}&>(immer::detail::hamts::node, unsigned int, fuzzer_input&&) const
Line
Count
Source
313
42.6k
    {
314
42.6k
        if (depth < max_depth<B>) {
315
40.7k
            auto datamap = node->datamap();
316
40.7k
            if (datamap)
317
13.8k
                fn(node->values(), node->values() + node->data_count());
318
40.7k
            auto nodemap = node->nodemap();
319
40.7k
            if (nodemap) {
320
27.9k
                auto fst = node->children();
321
27.9k
                auto lst = fst + node->children_count();
322
57.5k
                for (; fst != lst; ++fst)
323
29.5k
                    for_each_chunk_traversal(*fst, depth + 1, fn);
324
27.9k
            }
325
40.7k
        } else {
326
1.92k
            fn(node->collisions(),
327
1.92k
               node->collisions() + node->collision_count());
328
1.92k
        }
329
42.6k
    }
330
331
    template <typename EqualValue, typename Differ>
332
    void diff(const champ& new_champ, Differ&& differ) const
333
28.7k
    {
334
28.7k
        diff<EqualValue>(root, new_champ.root, 0, std::forward<Differ>(differ));
335
28.7k
    }
336
337
    template <typename EqualValue, typename Differ>
338
    void diff(const node_t* old_node,
339
              const node_t* new_node,
340
              count_t depth,
341
              Differ&& differ) const
342
684k
    {
343
684k
        if (old_node == new_node)
344
61.6k
            return;
345
622k
        if (depth < max_depth<B>) {
346
617k
            auto old_nodemap = old_node->nodemap();
347
617k
            auto new_nodemap = new_node->nodemap();
348
617k
            auto old_datamap = old_node->datamap();
349
617k
            auto new_datamap = new_node->datamap();
350
617k
            auto old_bits    = old_nodemap | old_datamap;
351
617k
            auto new_bits    = new_nodemap | new_datamap;
352
617k
            auto changes     = old_bits ^ new_bits;
353
354
            // added bits
355
617k
            for (auto bit : set_bits_range<bitmap_t>(new_bits & changes)) {
356
111k
                if (new_nodemap & bit) {
357
19.2k
                    auto offset = new_node->children_count(bit);
358
19.2k
                    auto child  = new_node->children()[offset];
359
19.2k
                    for_each_chunk_traversal(
360
19.2k
                        child,
361
19.2k
                        depth + 1,
362
23.3k
                        [&](auto const& begin, auto const& end) {
363
72.4k
                            for (auto it = begin; it != end; it++)
364
49.0k
                                differ.added(*it);
365
23.3k
                        });
map-st-str-conflict.cpp:auto immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}::operator()<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const*, {lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const, std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const* const) const
Line
Count
Source
362
1.79k
                        [&](auto const& begin, auto const& end) {
363
5.59k
                            for (auto it = begin; it != end; it++)
364
3.80k
                                differ.added(*it);
365
1.79k
                        });
map-st-str-conflict.cpp:auto immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}::operator()<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const*, {lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#1}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const, std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const* const) const
Line
Count
Source
362
21.6k
                        [&](auto const& begin, auto const& end) {
363
66.8k
                            for (auto it = begin; it != end; it++)
364
45.2k
                                differ.added(*it);
365
21.6k
                        });
366
92.4k
                } else if (new_datamap & bit) {
367
92.4k
                    auto offset       = new_node->data_count(bit);
368
92.4k
                    auto const& value = new_node->values()[offset];
369
92.4k
                    differ.added(value);
370
92.4k
                }
371
111k
            }
372
373
            // removed bits
374
617k
            for (auto bit : set_bits_range<bitmap_t>(old_bits & changes)) {
375
110k
                if (old_nodemap & bit) {
376
20.2k
                    auto offset = old_node->children_count(bit);
377
20.2k
                    auto child  = old_node->children()[offset];
378
20.2k
                    for_each_chunk_traversal(
379
20.2k
                        child,
380
20.2k
                        depth + 1,
381
27.7k
                        [&](auto const& begin, auto const& end) {
382
86.9k
                            for (auto it = begin; it != end; it++)
383
59.1k
                                differ.removed(*it);
384
27.7k
                        });
map-st-str-conflict.cpp:auto immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}::operator()<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const*, {lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const, std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const* const) const
Line
Count
Source
381
5.59k
                        [&](auto const& begin, auto const& end) {
382
17.2k
                            for (auto it = begin; it != end; it++)
383
11.6k
                                differ.removed(*it);
384
5.59k
                        });
map-st-str-conflict.cpp:auto immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const::{lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}::operator()<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const*, {lambda(auto:1 const&, {lambda(auto:1&&)#2} const&)#2}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const, std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > const* const) const
Line
Count
Source
381
22.1k
                        [&](auto const& begin, auto const& end) {
382
69.6k
                            for (auto it = begin; it != end; it++)
383
47.5k
                                differ.removed(*it);
384
22.1k
                        });
385
90.5k
                } else if (old_datamap & bit) {
386
90.5k
                    auto offset       = old_node->data_count(bit);
387
90.5k
                    auto const& value = old_node->values()[offset];
388
90.5k
                    differ.removed(value);
389
90.5k
                }
390
110k
            }
391
392
            // bits in both nodes
393
1.20M
            for (auto bit : set_bits_range<bitmap_t>(old_bits & new_bits)) {
394
1.20M
                if ((old_nodemap & bit) && (new_nodemap & bit)) {
395
655k
                    auto old_offset = old_node->children_count(bit);
396
655k
                    auto new_offset = new_node->children_count(bit);
397
655k
                    auto old_child  = old_node->children()[old_offset];
398
655k
                    auto new_child  = new_node->children()[new_offset];
399
655k
                    diff<EqualValue>(old_child, new_child, depth + 1, differ);
400
655k
                } else if ((old_datamap & bit) && (new_nodemap & bit)) {
401
41.2k
                    diff_data_node<EqualValue>(
402
41.2k
                        old_node, new_node, bit, depth, differ);
403
511k
                } else if ((old_nodemap & bit) && (new_datamap & bit)) {
404
41.0k
                    diff_node_data<EqualValue>(
405
41.0k
                        old_node, new_node, bit, depth, differ);
406
470k
                } else if ((old_datamap & bit) && (new_datamap & bit)) {
407
470k
                    diff_data_data<EqualValue>(old_node, new_node, bit, differ);
408
470k
                }
409
1.20M
            }
410
617k
        } else {
411
5.10k
            diff_collisions<EqualValue>(old_node, new_node, differ);
412
5.10k
        }
413
622k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}> >(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const
Line
Count
Source
342
28.7k
    {
343
28.7k
        if (old_node == new_node)
344
1.93k
            return;
345
26.7k
        if (depth < max_depth<B>) {
346
26.7k
            auto old_nodemap = old_node->nodemap();
347
26.7k
            auto new_nodemap = new_node->nodemap();
348
26.7k
            auto old_datamap = old_node->datamap();
349
26.7k
            auto new_datamap = new_node->datamap();
350
26.7k
            auto old_bits    = old_nodemap | old_datamap;
351
26.7k
            auto new_bits    = new_nodemap | new_datamap;
352
26.7k
            auto changes     = old_bits ^ new_bits;
353
354
            // added bits
355
26.7k
            for (auto bit : set_bits_range<bitmap_t>(new_bits & changes)) {
356
1.29k
                if (new_nodemap & bit) {
357
1.00k
                    auto offset = new_node->children_count(bit);
358
1.00k
                    auto child  = new_node->children()[offset];
359
1.00k
                    for_each_chunk_traversal(
360
1.00k
                        child,
361
1.00k
                        depth + 1,
362
1.00k
                        [&](auto const& begin, auto const& end) {
363
1.00k
                            for (auto it = begin; it != end; it++)
364
1.00k
                                differ.added(*it);
365
1.00k
                        });
366
1.00k
                } else if (new_datamap & bit) {
367
286
                    auto offset       = new_node->data_count(bit);
368
286
                    auto const& value = new_node->values()[offset];
369
286
                    differ.added(value);
370
286
                }
371
1.29k
            }
372
373
            // removed bits
374
26.7k
            for (auto bit : set_bits_range<bitmap_t>(old_bits & changes)) {
375
2.16k
                if (old_nodemap & bit) {
376
1.85k
                    auto offset = old_node->children_count(bit);
377
1.85k
                    auto child  = old_node->children()[offset];
378
1.85k
                    for_each_chunk_traversal(
379
1.85k
                        child,
380
1.85k
                        depth + 1,
381
1.85k
                        [&](auto const& begin, auto const& end) {
382
1.85k
                            for (auto it = begin; it != end; it++)
383
1.85k
                                differ.removed(*it);
384
1.85k
                        });
385
1.85k
                } else if (old_datamap & bit) {
386
306
                    auto offset       = old_node->data_count(bit);
387
306
                    auto const& value = old_node->values()[offset];
388
306
                    differ.removed(value);
389
306
                }
390
2.16k
            }
391
392
            // bits in both nodes
393
26.7k
            for (auto bit : set_bits_range<bitmap_t>(old_bits & new_bits)) {
394
23.3k
                if ((old_nodemap & bit) && (new_nodemap & bit)) {
395
19.4k
                    auto old_offset = old_node->children_count(bit);
396
19.4k
                    auto new_offset = new_node->children_count(bit);
397
19.4k
                    auto old_child  = old_node->children()[old_offset];
398
19.4k
                    auto new_child  = new_node->children()[new_offset];
399
19.4k
                    diff<EqualValue>(old_child, new_child, depth + 1, differ);
400
19.4k
                } else if ((old_datamap & bit) && (new_nodemap & bit)) {
401
1.62k
                    diff_data_node<EqualValue>(
402
1.62k
                        old_node, new_node, bit, depth, differ);
403
2.23k
                } else if ((old_nodemap & bit) && (new_datamap & bit)) {
404
1.45k
                    diff_node_data<EqualValue>(
405
1.45k
                        old_node, new_node, bit, depth, differ);
406
1.45k
                } else if ((old_datamap & bit) && (new_datamap & bit)) {
407
777
                    diff_data_data<EqualValue>(old_node, new_node, bit, differ);
408
777
                }
409
23.3k
            }
410
26.7k
        } else {
411
0
            diff_collisions<EqualValue>(old_node, new_node, differ);
412
0
        }
413
26.7k
    }
map-st-str-conflict.cpp:void immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::diff<std::__1::equal_to<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > > >, immer::differ<LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#1}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&, auto:2&&)#1}>&>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u> const*, immer::detail::hamts::node, unsigned int, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(auto:1&&)#2}) const
Line
Count
Source
342
655k
    {
343
655k
        if (old_node == new_node)
344
59.7k
            return;
345
595k
        if (depth < max_depth<B>) {
346
590k
            auto old_nodemap = old_node->nodemap();
347
590k
            auto new_nodemap = new_node->nodemap();
348
590k
            auto old_datamap = old_node->datamap();
349
590k
            auto new_datamap = new_node->datamap();
350
590k
            auto old_bits    = old_nodemap | old_datamap;
351
590k
            auto new_bits    = new_nodemap | new_datamap;
352
590k
            auto changes     = old_bits ^ new_bits;
353
354
            // added bits
355
590k
            for (auto bit : set_bits_range<bitmap_t>(new_bits & changes)) {
356
110k
                if (new_nodemap & bit) {
357
18.2k
                    auto offset = new_node->children_count(bit);
358
18.2k
                    auto child  = new_node->children()[offset];
359
18.2k
                    for_each_chunk_traversal(
360
18.2k
                        child,
361
18.2k
                        depth + 1,
362
18.2k
                        [&](auto const& begin, auto const& end) {
363
18.2k
                            for (auto it = begin; it != end; it++)
364
18.2k
                                differ.added(*it);
365
18.2k
                        });
366
92.1k
                } else if (new_datamap & bit) {
367
92.1k
                    auto offset       = new_node->data_count(bit);
368
92.1k
                    auto const& value = new_node->values()[offset];
369
92.1k
                    differ.added(value);
370
92.1k
                }
371
110k
            }
372
373
            // removed bits
374
590k
            for (auto bit : set_bits_range<bitmap_t>(old_bits & changes)) {
375
108k
                if (old_nodemap & bit) {
376
18.3k
                    auto offset = old_node->children_count(bit);
377
18.3k
                    auto child  = old_node->children()[offset];
378
18.3k
                    for_each_chunk_traversal(
379
18.3k
                        child,
380
18.3k
                        depth + 1,
381
18.3k
                        [&](auto const& begin, auto const& end) {
382
18.3k
                            for (auto it = begin; it != end; it++)
383
18.3k
                                differ.removed(*it);
384
18.3k
                        });
385
90.2k
                } else if (old_datamap & bit) {
386
90.2k
                    auto offset       = old_node->data_count(bit);
387
90.2k
                    auto const& value = old_node->values()[offset];
388
90.2k
                    differ.removed(value);
389
90.2k
                }
390
108k
            }
391
392
            // bits in both nodes
393
1.18M
            for (auto bit : set_bits_range<bitmap_t>(old_bits & new_bits)) {
394
1.18M
                if ((old_nodemap & bit) && (new_nodemap & bit)) {
395
635k
                    auto old_offset = old_node->children_count(bit);
396
635k
                    auto new_offset = new_node->children_count(bit);
397
635k
                    auto old_child  = old_node->children()[old_offset];
398
635k
                    auto new_child  = new_node->children()[new_offset];
399
635k
                    diff<EqualValue>(old_child, new_child, depth + 1, differ);
400
635k
                } else if ((old_datamap & bit) && (new_nodemap & bit)) {
401
39.6k
                    diff_data_node<EqualValue>(
402
39.6k
                        old_node, new_node, bit, depth, differ);
403
508k
                } else if ((old_nodemap & bit) && (new_datamap & bit)) {
404
39.5k
                    diff_node_data<EqualValue>(
405
39.5k
                        old_node, new_node, bit, depth, differ);
406
469k
                } else if ((old_datamap & bit) && (new_datamap & bit)) {
407
469k
                    diff_data_data<EqualValue>(old_node, new_node, bit, differ);
408
469k
                }
409
1.18M
            }
410
590k
        } else {
411
5.10k
            diff_collisions<EqualValue>(old_node, new_node, differ);
412
5.10k
        }
413
595k
    }
414
415
    template <typename EqualValue, typename Differ>
416
    void diff_data_node(const node_t* old_node,
417
                        const node_t* new_node,
418
                        bitmap_t bit,
419
                        count_t depth,
420
                        Differ&& differ) const
421
41.2k
    {
422
41.2k
        auto old_offset       = old_node->data_count(bit);
423
41.2k
        auto const& old_value = old_node->values()[old_offset];
424
41.2k
        auto new_offset       = new_node->children_count(bit);
425
41.2k
        auto new_child        = new_node->children()[new_offset];
426
427
41.2k
        bool found = false;
428
41.2k
        for_each_chunk_traversal(
429
50.0k
            new_child, depth + 1, [&](auto const& begin, auto const& end) {
430
154k
                for (auto it = begin; it != end; it++) {
431
104k
                    if (Equal{}(old_value, *it)) {
432
28.8k
                        if (!EqualValue{}(old_value, *it))
433
2.72k
                            differ.changed(old_value, *it);
434
28.8k
                        found = true;
435
75.1k
                    } else {
436
75.1k
                        differ.added(*it);
437
75.1k
                    }
438
104k
                }
439
50.0k
            });
440
41.2k
        if (!found)
441
12.4k
            differ.removed(old_value);
442
41.2k
    }
443
444
    template <typename EqualValue, typename Differ>
445
    void diff_node_data(const node_t* old_node,
446
                        const node_t* const new_node,
447
                        bitmap_t bit,
448
                        count_t depth,
449
                        Differ&& differ) const
450
41.0k
    {
451
41.0k
        auto old_offset       = old_node->children_count(bit);
452
41.0k
        auto old_child        = old_node->children()[old_offset];
453
41.0k
        auto new_offset       = new_node->data_count(bit);
454
41.0k
        auto const& new_value = new_node->values()[new_offset];
455
456
41.0k
        bool found = false;
457
41.0k
        for_each_chunk_traversal(
458
49.1k
            old_child, depth + 1, [&](auto const& begin, auto const& end) {
459
152k
                for (auto it = begin; it != end; it++) {
460
103k
                    if (Equal{}(*it, new_value)) {
461
28.5k
                        if (!EqualValue{}(*it, new_value))
462
2.46k
                            differ.changed(*it, new_value);
463
28.5k
                        found = true;
464
74.4k
                    } else {
465
74.4k
                        differ.removed(*it);
466
74.4k
                    }
467
103k
                }
468
49.1k
            });
469
41.0k
        if (!found)
470
12.4k
            differ.added(new_value);
471
41.0k
    }
472
473
    template <typename EqualValue, typename Differ>
474
    void diff_data_data(const node_t* old_node,
475
                        const node_t* new_node,
476
                        bitmap_t bit,
477
                        Differ&& differ) const
478
470k
    {
479
470k
        auto old_offset       = old_node->data_count(bit);
480
470k
        auto new_offset       = new_node->data_count(bit);
481
470k
        auto const& old_value = old_node->values()[old_offset];
482
470k
        auto const& new_value = new_node->values()[new_offset];
483
470k
        if (!Equal{}(old_value, new_value)) {
484
26.0k
            differ.removed(old_value);
485
26.0k
            differ.added(new_value);
486
443k
        } else {
487
443k
            if (!EqualValue{}(old_value, new_value))
488
18.8k
                differ.changed(old_value, new_value);
489
443k
        }
490
470k
    }
491
492
    template <typename EqualValue, typename Differ>
493
    void diff_collisions(const node_t* old_node,
494
                         const node_t* new_node,
495
                         Differ&& differ) const
496
5.10k
    {
497
5.10k
        auto old_begin = old_node->collisions();
498
5.10k
        auto old_end   = old_node->collisions() + old_node->collision_count();
499
5.10k
        auto new_begin = new_node->collisions();
500
5.10k
        auto new_end   = new_node->collisions() + new_node->collision_count();
501
        // search changes and removals
502
16.7k
        for (auto old_it = old_begin; old_it != old_end; old_it++) {
503
11.6k
            bool found = false;
504
20.9k
            for (auto new_it = new_begin; new_it != new_end; new_it++) {
505
20.1k
                if (Equal{}(*old_it, *new_it)) {
506
10.8k
                    if (!EqualValue{}(*old_it, *new_it))
507
452
                        differ.changed(*old_it, *new_it);
508
10.8k
                    found = true;
509
10.8k
                    break;
510
10.8k
                }
511
20.1k
            }
512
11.6k
            if (!found)
513
758
                differ.removed(*old_it);
514
11.6k
        }
515
        // search new entries
516
16.5k
        for (auto new_it = new_begin; new_it != new_end; new_it++) {
517
11.4k
            bool found = false;
518
20.5k
            for (auto old_it = old_begin; old_it != old_end; old_it++) {
519
19.9k
                if (Equal{}(*old_it, *new_it)) {
520
10.8k
                    found = true;
521
10.8k
                    break;
522
10.8k
                }
523
19.9k
            }
524
11.4k
            if (!found)
525
578
                differ.added(*new_it);
526
11.4k
        }
527
5.10k
    }
528
529
    template <typename Project, typename Default, typename K>
530
    decltype(auto) get(const K& k) const
531
1.04M
    {
532
1.04M
        auto node = root;
533
1.04M
        auto hash = Hash{}(k);
534
18.6M
        for (auto i = count_t{}; i < max_depth<B>; ++i) {
535
18.6M
            auto bit = bitmap_t{1u} << (hash & mask<B>);
536
18.6M
            if (node->nodemap() & bit) {
537
17.6M
                auto offset = node->children_count(bit);
538
17.6M
                node        = node->children()[offset];
539
17.6M
                hash        = hash >> B;
540
17.6M
            } else if (node->datamap() & bit) {
541
719k
                auto offset = node->data_count(bit);
542
719k
                auto val    = node->values() + offset;
543
719k
                if (Equal{}(*val, k))
544
511k
                    return Project{}(*val);
545
208k
                else
546
208k
                    return Default{}();
547
719k
            } else {
548
311k
                return Default{}();
549
311k
            }
550
18.6M
        }
551
16.5k
        auto fst = node->collisions();
552
16.5k
        auto lst = fst + node->collision_count();
553
29.9k
        for (; fst != lst; ++fst)
554
28.1k
            if (Equal{}(*fst, k))
555
14.6k
                return Project{}(*fst);
556
1.84k
        return Default{}();
557
16.5k
    }
decltype(auto) immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::get<immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::project_value_ptr, immer::detail::constantly<immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > const*, (immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > const*)0>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const
Line
Count
Source
531
9.51k
    {
532
9.51k
        auto node = root;
533
9.51k
        auto hash = Hash{}(k);
534
154k
        for (auto i = count_t{}; i < max_depth<B>; ++i) {
535
153k
            auto bit = bitmap_t{1u} << (hash & mask<B>);
536
153k
            if (node->nodemap() & bit) {
537
144k
                auto offset = node->children_count(bit);
538
144k
                node        = node->children()[offset];
539
144k
                hash        = hash >> B;
540
144k
            } else if (node->datamap() & bit) {
541
7.23k
                auto offset = node->data_count(bit);
542
7.23k
                auto val    = node->values() + offset;
543
7.23k
                if (Equal{}(*val, k))
544
6.15k
                    return Project{}(*val);
545
1.08k
                else
546
1.08k
                    return Default{}();
547
7.23k
            } else {
548
1.07k
                return Default{}();
549
1.07k
            }
550
153k
        }
551
1.20k
        auto fst = node->collisions();
552
1.20k
        auto lst = fst + node->collision_count();
553
3.08k
        for (; fst != lst; ++fst)
554
2.60k
            if (Equal{}(*fst, k))
555
721
                return Project{}(*fst);
556
481
        return Default{}();
557
1.20k
    }
decltype(auto) immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::get<immer::detail::constantly<unsigned long, 1ul>, immer::detail::constantly<unsigned long, 0ul>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const
Line
Count
Source
531
1.03M
    {
532
1.03M
        auto node = root;
533
1.03M
        auto hash = Hash{}(k);
534
18.5M
        for (auto i = count_t{}; i < max_depth<B>; ++i) {
535
18.4M
            auto bit = bitmap_t{1u} << (hash & mask<B>);
536
18.4M
            if (node->nodemap() & bit) {
537
17.4M
                auto offset = node->children_count(bit);
538
17.4M
                node        = node->children()[offset];
539
17.4M
                hash        = hash >> B;
540
17.4M
            } else if (node->datamap() & bit) {
541
712k
                auto offset = node->data_count(bit);
542
712k
                auto val    = node->values() + offset;
543
712k
                if (Equal{}(*val, k))
544
505k
                    return Project{}(*val);
545
206k
                else
546
206k
                    return Default{}();
547
712k
            } else {
548
310k
                return Default{}();
549
310k
            }
550
18.4M
        }
551
15.3k
        auto fst = node->collisions();
552
15.3k
        auto lst = fst + node->collision_count();
553
26.8k
        for (; fst != lst; ++fst)
554
25.5k
            if (Equal{}(*fst, k))
555
13.9k
                return Project{}(*fst);
556
1.36k
        return Default{}();
557
15.3k
    }
558
559
    struct add_result
560
    {
561
        node_t* node;
562
        bool added;
563
    };
564
565
    add_result do_add(node_t* node, T v, hash_t hash, shift_t shift) const
566
12.8M
    {
567
12.8M
        assert(node);
568
12.8M
        if (shift == max_shift<B>) {
569
24.1k
            auto fst = node->collisions();
570
24.1k
            auto lst = fst + node->collision_count();
571
58.3k
            for (; fst != lst; ++fst)
572
56.8k
                if (Equal{}(*fst, v))
573
22.6k
                    return {
574
22.6k
                        node_t::copy_collision_replace(node, fst, std::move(v)),
575
22.6k
                        false};
576
1.46k
            return {node_t::copy_collision_insert(node, std::move(v)), true};
577
12.8M
        } else {
578
12.8M
            auto idx = (hash & (mask<B> << shift)) >> shift;
579
12.8M
            auto bit = bitmap_t{1u} << idx;
580
12.8M
            if (node->nodemap() & bit) {
581
12.1M
                auto offset = node->children_count(bit);
582
12.1M
                assert(node->children()[offset]);
583
0
                auto result = do_add(
584
12.1M
                    node->children()[offset], std::move(v), hash, shift + B);
585
12.1M
                IMMER_TRY {
586
12.1M
                    result.node =
587
12.1M
                        node_t::copy_inner_replace(node, offset, result.node);
588
12.1M
                    return result;
589
12.1M
                }
590
12.1M
                IMMER_CATCH (...) {
591
0
                    node_t::delete_deep_shift(result.node, shift + B);
592
0
                    IMMER_RETHROW;
593
0
                }
594
12.1M
            } else if (node->datamap() & bit) {
595
625k
                auto offset = node->data_count(bit);
596
625k
                auto val    = node->values() + offset;
597
625k
                if (Equal{}(*val, v))
598
603k
                    return {node_t::copy_inner_replace_value(
599
603k
                                node, offset, std::move(v)),
600
603k
                            false};
601
21.2k
                else {
602
21.2k
                    auto child = node_t::make_merged(
603
21.2k
                        shift + B, std::move(v), hash, *val, Hash{}(*val));
604
21.2k
                    IMMER_TRY {
605
21.2k
                        return {node_t::copy_inner_replace_merged(
606
21.2k
                                    node, bit, offset, child),
607
21.2k
                                true};
608
21.2k
                    }
609
21.2k
                    IMMER_CATCH (...) {
610
0
                        node_t::delete_deep_shift(child, shift + B);
611
0
                        IMMER_RETHROW;
612
0
                    }
613
21.2k
                }
614
625k
            } else {
615
27.3k
                return {
616
27.3k
                    node_t::copy_inner_insert_value(node, bit, std::move(v)),
617
27.3k
                    true};
618
27.3k
            }
619
12.8M
        }
620
12.8M
    }
621
622
    champ add(T v) const
623
674k
    {
624
674k
        auto hash     = Hash{}(v);
625
674k
        auto res      = do_add(root, std::move(v), hash, 0);
626
674k
        auto new_size = size + (res.added ? 1 : 0);
627
674k
        return {res.node, new_size};
628
674k
    }
629
630
    struct add_mut_result
631
    {
632
        node_t* node;
633
        bool added;
634
        bool mutated;
635
    };
636
637
    add_mut_result
638
    do_add_mut(edit_t e, node_t* node, T v, hash_t hash, shift_t shift) const
639
358k
    {
640
358k
        assert(node);
641
358k
        if (shift == max_shift<B>) {
642
1.90k
            auto fst = node->collisions();
643
1.90k
            auto lst = fst + node->collision_count();
644
4.49k
            for (; fst != lst; ++fst)
645
3.89k
                if (Equal{}(*fst, v)) {
646
1.31k
                    if (node->can_mutate(e)) {
647
1.02k
                        *fst = std::move(v);
648
1.02k
                        return {node, false, true};
649
1.02k
                    } else {
650
288
                        auto r = node_t::copy_collision_replace(
651
288
                            node, fst, std::move(v));
652
288
                        return {node_t::owned(r, e), false, false};
653
288
                    }
654
1.31k
                }
655
592
            auto mutate = node->can_mutate(e);
656
592
            auto r = mutate ? node_t::move_collision_insert(node, std::move(v))
657
592
                            : node_t::copy_collision_insert(node, std::move(v));
658
592
            return {node_t::owned(r, e), true, mutate};
659
356k
        } else {
660
356k
            auto idx = (hash & (mask<B> << shift)) >> shift;
661
356k
            auto bit = bitmap_t{1u} << idx;
662
356k
            if (node->nodemap() & bit) {
663
338k
                auto offset = node->children_count(bit);
664
338k
                auto child  = node->children()[offset];
665
338k
                if (node->can_mutate(e)) {
666
335k
                    auto result =
667
335k
                        do_add_mut(e, child, std::move(v), hash, shift + B);
668
335k
                    node->children()[offset] = result.node;
669
335k
                    if (!result.mutated && child->dec())
670
0
                        node_t::delete_deep_shift(child, shift + B);
671
335k
                    return {node, result.added, true};
672
335k
                } else {
673
2.39k
                    assert(node->children()[offset]);
674
0
                    auto result = do_add(child, std::move(v), hash, shift + B);
675
2.39k
                    IMMER_TRY {
676
2.39k
                        result.node = node_t::copy_inner_replace(
677
2.39k
                            node, offset, result.node);
678
2.39k
                        node_t::owned(result.node, e);
679
2.39k
                        return {result.node, result.added, false};
680
2.39k
                    }
681
2.39k
                    IMMER_CATCH (...) {
682
0
                        node_t::delete_deep_shift(result.node, shift + B);
683
0
                        IMMER_RETHROW;
684
0
                    }
685
2.39k
                }
686
338k
            } else if (node->datamap() & bit) {
687
12.2k
                auto offset = node->data_count(bit);
688
12.2k
                auto val    = node->values() + offset;
689
12.2k
                if (Equal{}(*val, v)) {
690
6.56k
                    if (node->can_mutate(e)) {
691
6.03k
                        auto vals    = node->ensure_mutable_values(e);
692
6.03k
                        vals[offset] = std::move(v);
693
6.03k
                        return {node, false, true};
694
6.03k
                    } else {
695
535
                        auto r = node_t::copy_inner_replace_value(
696
535
                            node, offset, std::move(v));
697
535
                        return {node_t::owned_values(r, e), false, false};
698
535
                    }
699
6.56k
                } else {
700
5.67k
                    auto mutate        = node->can_mutate(e);
701
5.67k
                    auto mutate_values = mutate && node->can_mutate_values(e);
702
5.67k
                    auto hash2         = Hash{}(*val);
703
5.67k
                    auto child         = node_t::make_merged_e(
704
5.67k
                        e,
705
5.67k
                        shift + B,
706
5.67k
                        std::move(v),
707
5.67k
                        hash,
708
5.67k
                        mutate_values ? std::move(*val) : *val,
709
5.67k
                        hash2);
710
5.67k
                    IMMER_TRY {
711
5.67k
                        auto r = mutate ? node_t::move_inner_replace_merged(
712
4.68k
                                              e, node, bit, offset, child)
713
5.67k
                                        : node_t::copy_inner_replace_merged(
714
996
                                              node, bit, offset, child);
715
5.67k
                        return {node_t::owned_values_safe(r, e), true, mutate};
716
5.67k
                    }
717
5.67k
                    IMMER_CATCH (...) {
718
0
                        node_t::delete_deep_shift(child, shift + B);
719
0
                        IMMER_RETHROW;
720
0
                    }
721
5.67k
                }
722
12.2k
            } else {
723
5.71k
                auto mutate = node->can_mutate(e);
724
5.71k
                auto r      = mutate ? node_t::move_inner_insert_value(
725
3.90k
                                      e, node, bit, std::move(v))
726
5.71k
                                     : node_t::copy_inner_insert_value(
727
1.81k
                                      node, bit, std::move(v));
728
5.71k
                return {node_t::owned_values(r, e), true, mutate};
729
5.71k
            }
730
356k
        }
731
358k
    }
732
733
    void add_mut(edit_t e, T v)
734
22.2k
    {
735
22.2k
        auto hash = Hash{}(v);
736
22.2k
        auto res  = do_add_mut(e, root, std::move(v), hash, 0);
737
22.2k
        if (!res.mutated && root->dec())
738
0
            node_t::delete_deep(root, 0);
739
22.2k
        root = res.node;
740
22.2k
        size += res.added ? 1 : 0;
741
22.2k
    }
742
743
    using update_result = add_result;
744
745
    template <typename Project,
746
              typename Default,
747
              typename Combine,
748
              typename K,
749
              typename Fn>
750
    update_result
751
    do_update(node_t* node, K&& k, Fn&& fn, hash_t hash, shift_t shift) const
752
4.27M
    {
753
4.27M
        if (shift == max_shift<B>) {
754
2.31k
            auto fst = node->collisions();
755
2.31k
            auto lst = fst + node->collision_count();
756
5.32k
            for (; fst != lst; ++fst)
757
4.46k
                if (Equal{}(*fst, k))
758
1.45k
                    return {node_t::copy_collision_replace(
759
1.45k
                                node,
760
1.45k
                                fst,
761
1.45k
                                Combine{}(std::forward<K>(k),
762
1.45k
                                          std::forward<Fn>(fn)(Project{}(
763
1.45k
                                              detail::as_const(*fst))))),
764
1.45k
                            false};
765
857
            return {node_t::copy_collision_insert(
766
857
                        node,
767
857
                        Combine{}(std::forward<K>(k),
768
857
                                  std::forward<Fn>(fn)(Default{}()))),
769
857
                    true};
770
4.27M
        } else {
771
4.27M
            auto idx = (hash & (mask<B> << shift)) >> shift;
772
4.27M
            auto bit = bitmap_t{1u} << idx;
773
4.27M
            if (node->nodemap() & bit) {
774
4.04M
                auto offset = node->children_count(bit);
775
4.04M
                auto result = do_update<Project, Default, Combine>(
776
4.04M
                    node->children()[offset],
777
4.04M
                    k,
778
4.04M
                    std::forward<Fn>(fn),
779
4.04M
                    hash,
780
4.04M
                    shift + B);
781
4.04M
                IMMER_TRY {
782
4.04M
                    result.node =
783
4.04M
                        node_t::copy_inner_replace(node, offset, result.node);
784
4.04M
                    return result;
785
4.04M
                }
786
4.04M
                IMMER_CATCH (...) {
787
0
                    node_t::delete_deep_shift(result.node, shift + B);
788
0
                    IMMER_RETHROW;
789
0
                }
790
4.04M
            } else if (node->datamap() & bit) {
791
229k
                auto offset = node->data_count(bit);
792
229k
                auto val    = node->values() + offset;
793
229k
                if (Equal{}(*val, k))
794
224k
                    return {node_t::copy_inner_replace_value(
795
224k
                                node,
796
224k
                                offset,
797
224k
                                Combine{}(std::forward<K>(k),
798
224k
                                          std::forward<Fn>(fn)(Project{}(
799
224k
                                              detail::as_const(*val))))),
800
224k
                            false};
801
4.92k
                else {
802
4.92k
                    auto child = node_t::make_merged(
803
4.92k
                        shift + B,
804
4.92k
                        Combine{}(std::forward<K>(k),
805
4.92k
                                  std::forward<Fn>(fn)(Default{}())),
806
4.92k
                        hash,
807
4.92k
                        *val,
808
4.92k
                        Hash{}(*val));
809
4.92k
                    IMMER_TRY {
810
4.92k
                        return {node_t::copy_inner_replace_merged(
811
4.92k
                                    node, bit, offset, child),
812
4.92k
                                true};
813
4.92k
                    }
814
4.92k
                    IMMER_CATCH (...) {
815
0
                        node_t::delete_deep_shift(child, shift + B);
816
0
                        IMMER_RETHROW;
817
0
                    }
818
4.92k
                }
819
229k
            } else {
820
5.40k
                return {node_t::copy_inner_insert_value(
821
5.40k
                            node,
822
5.40k
                            bit,
823
5.40k
                            Combine{}(std::forward<K>(k),
824
5.40k
                                      std::forward<Fn>(fn)(Default{}()))),
825
5.40k
                        true};
826
5.40k
            }
827
4.27M
        }
828
4.27M
    }
map-st-str-conflict.cpp:immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::add_result immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::do_update<immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::project_value, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::default_value, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::combine_value, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)#1}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)#1}&&, unsigned long, unsigned int) const
Line
Count
Source
752
4.20M
    {
753
4.20M
        if (shift == max_shift<B>) {
754
1.06k
            auto fst = node->collisions();
755
1.06k
            auto lst = fst + node->collision_count();
756
2.58k
            for (; fst != lst; ++fst)
757
2.19k
                if (Equal{}(*fst, k))
758
670
                    return {node_t::copy_collision_replace(
759
670
                                node,
760
670
                                fst,
761
670
                                Combine{}(std::forward<K>(k),
762
670
                                          std::forward<Fn>(fn)(Project{}(
763
670
                                              detail::as_const(*fst))))),
764
670
                            false};
765
391
            return {node_t::copy_collision_insert(
766
391
                        node,
767
391
                        Combine{}(std::forward<K>(k),
768
391
                                  std::forward<Fn>(fn)(Default{}()))),
769
391
                    true};
770
4.20M
        } else {
771
4.20M
            auto idx = (hash & (mask<B> << shift)) >> shift;
772
4.20M
            auto bit = bitmap_t{1u} << idx;
773
4.20M
            if (node->nodemap() & bit) {
774
3.97M
                auto offset = node->children_count(bit);
775
3.97M
                auto result = do_update<Project, Default, Combine>(
776
3.97M
                    node->children()[offset],
777
3.97M
                    k,
778
3.97M
                    std::forward<Fn>(fn),
779
3.97M
                    hash,
780
3.97M
                    shift + B);
781
3.97M
                IMMER_TRY {
782
3.97M
                    result.node =
783
3.97M
                        node_t::copy_inner_replace(node, offset, result.node);
784
3.97M
                    return result;
785
3.97M
                }
786
3.97M
                IMMER_CATCH (...) {
787
0
                    node_t::delete_deep_shift(result.node, shift + B);
788
0
                    IMMER_RETHROW;
789
0
                }
790
3.97M
            } else if (node->datamap() & bit) {
791
226k
                auto offset = node->data_count(bit);
792
226k
                auto val    = node->values() + offset;
793
226k
                if (Equal{}(*val, k))
794
222k
                    return {node_t::copy_inner_replace_value(
795
222k
                                node,
796
222k
                                offset,
797
222k
                                Combine{}(std::forward<K>(k),
798
222k
                                          std::forward<Fn>(fn)(Project{}(
799
222k
                                              detail::as_const(*val))))),
800
222k
                            false};
801
3.70k
                else {
802
3.70k
                    auto child = node_t::make_merged(
803
3.70k
                        shift + B,
804
3.70k
                        Combine{}(std::forward<K>(k),
805
3.70k
                                  std::forward<Fn>(fn)(Default{}())),
806
3.70k
                        hash,
807
3.70k
                        *val,
808
3.70k
                        Hash{}(*val));
809
3.70k
                    IMMER_TRY {
810
3.70k
                        return {node_t::copy_inner_replace_merged(
811
3.70k
                                    node, bit, offset, child),
812
3.70k
                                true};
813
3.70k
                    }
814
3.70k
                    IMMER_CATCH (...) {
815
0
                        node_t::delete_deep_shift(child, shift + B);
816
0
                        IMMER_RETHROW;
817
0
                    }
818
3.70k
                }
819
226k
            } else {
820
4.14k
                return {node_t::copy_inner_insert_value(
821
4.14k
                            node,
822
4.14k
                            bit,
823
4.14k
                            Combine{}(std::forward<K>(k),
824
4.14k
                                      std::forward<Fn>(fn)(Default{}()))),
825
4.14k
                        true};
826
4.14k
            }
827
4.20M
        }
828
4.20M
    }
map-st-str-conflict.cpp:immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::add_result immer::detail::hamts::champ<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::do_update<immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::project_value, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::default_value, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::combine_value, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)#2}>(immer::detail::hamts::node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> > >, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::hash_key, immer::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::box<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true> >, colliding_hash_t, std::__1::equal_to<void>, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>::equal_key, immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy, immer::no_lock_policy, immer::no_transience_policy, false, true>, 3u>*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, LLVMFuzzerTestOneInput::$_1::operator()<fuzzer_input>(fuzzer_input&) const::{lambda(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)#2}&&, unsigned long, unsigned int) const
Line
Count
Source
752
75.3k
    {
753
75.3k
        if (shift == max_shift<B>) {
754
1.25k
            auto fst = node->collisions();
755
1.25k
            auto lst = fst + node->collision_count();
756
2.73k
            for (; fst != lst; ++fst)
757
2.27k
                if (Equal{}(*fst, k))
758
789
                    return {node_t::copy_collision_replace(
759
789
                                node,
760
789
                                fst,
761
789
                                Combine{}(std::forward<K>(k),
762
789
                                          std::forward<Fn>(fn)(Project{}(
763
789
                                              detail::as_const(*fst))))),
764
789
                            false};
765
466
            return {node_t::copy_collision_insert(
766
466
                        node,
767
466
                        Combine{}(std::forward<K>(k),
768
466
                                  std::forward<Fn>(fn)(Default{}()))),
769
466
                    true};
770
74.0k
        } else {
771
74.0k
            auto idx = (hash & (mask<B> << shift)) >> shift;
772
74.0k
            auto bit = bitmap_t{1u} << idx;
773
74.0k
            if (node->nodemap() & bit) {
774
69.4k
                auto offset = node->children_count(bit);
775
69.4k
                auto result = do_update<Project, Default, Combine>(
776
69.4k
                    node->children()[offset],
777
69.4k
                    k,
778
69.4k
                    std::forward<Fn>(fn),
779
69.4k
                    hash,
780
69.4k
                    shift + B);
781
69.4k
                IMMER_TRY {
782
69.4k
                    result.node =
783
69.4k
                        node_t::copy_inner_replace(node, offset, result.node);
784
69.4k
                    return result;
785
69.4k
                }
786
69.4k
                IMMER_CATCH (...) {
787
0
                    node_t::delete_deep_shift(result.node, shift + B);
788
0
                    IMMER_RETHROW;
789
0
                }
790
69.4k
            } else if (node->datamap() & bit) {
791
3.33k
                auto offset = node->data_count(bit);
792
3.33k
                auto val    = node->values() + offset;
793
3.33k
                if (Equal{}(*val, k))
794
2.10k
                    return {node_t::copy_inner_replace_value(
795
2.10k
                                node,
796
2.10k
                                offset,
797
2.10k
                                Combine{}(std::forward<K>(k),
798
2.10k
                                          std::forward<Fn>(fn)(Project{}(
799
2.10k
                                              detail::as_const(*val))))),
800
2.10k
                            false};
801
1.22k
                else {
802
1.22k
                    auto child = node_t::make_merged(
803
1.22k
                        shift + B,
804
1.22k
                        Combine{}(std::forward<K>(k),
805
1.22k
                                  std::forward<Fn>(fn)(Default{}())),
806
1.22k
                        hash,
807
1.22k
                        *val,
808
1.22k
                        Hash{}(*val));
809
1.22k
                    IMMER_TRY {
810
1.22k
                        return {node_t::copy_inner_replace_merged(
811
1.22k
                                    node, bit, offset, child),
812
1.22k
                                true};
813
1.22k
                    }
814
1.22k
                    IMMER_CATCH (...) {
815
0
                        node_t::delete_deep_shift(child, shift + B);
816
0
                        IMMER_RETHROW;
817
0
                    }
818
1.22k
                }
819
3.33k
            } else {
820
1.26k
                return {node_t::copy_inner_insert_value(
821
1.26k
                            node,
822
1.26k
                            bit,
823
1.26k
                            Combine{}(std::forward<K>(k),
824
1.26k
                                      std::forward<Fn>(fn)(Default{}()))),
825
1.26k
                        true};
826
1.26k
            }
827
74.0k
        }
828
75.3k
    }
829
830
    template <typename Project,
831
              typename Default,
832
              typename Combine,
833
              typename K,
834
              typename Fn>
835
    champ update(const K& k, Fn&& fn) const
836
231k
    {
837
231k
        auto hash = Hash{}(k);
838
231k
        auto res  = do_update<Project, Default, Combine>(
839
231k
            root, k, std::forward<Fn>(fn), hash, 0);
840
231k
        auto new_size = size + (res.added ? 1 : 0);
841
231k
        return {res.node, new_size};
842
231k
    }
843
844
    template <typename Project, typename Combine, typename K, typename Fn>
845
    node_t* do_update_if_exists(
846
        node_t* node, K&& k, Fn&& fn, hash_t hash, shift_t shift) const
847
    {
848
        if (shift == max_shift<B>) {
849
            auto fst = node->collisions();
850
            auto lst = fst + node->collision_count();
851
            for (; fst != lst; ++fst)
852
                if (Equal{}(*fst, k))
853
                    return node_t::copy_collision_replace(
854
                        node,
855
                        fst,
856
                        Combine{}(std::forward<K>(k),
857
                                  std::forward<Fn>(fn)(
858
                                      Project{}(detail::as_const(*fst)))));
859
            return nullptr;
860
        } else {
861
            auto idx = (hash & (mask<B> << shift)) >> shift;
862
            auto bit = bitmap_t{1u} << idx;
863
            if (node->nodemap() & bit) {
864
                auto offset = node->children_count(bit);
865
                auto result = do_update_if_exists<Project, Combine>(
866
                    node->children()[offset],
867
                    k,
868
                    std::forward<Fn>(fn),
869
                    hash,
870
                    shift + B);
871
                IMMER_TRY {
872
                    return result ? node_t::copy_inner_replace(
873
                                        node, offset, result)
874
                                  : nullptr;
875
                }
876
                IMMER_CATCH (...) {
877
                    node_t::delete_deep_shift(result, shift + B);
878
                    IMMER_RETHROW;
879
                }
880
            } else if (node->datamap() & bit) {
881
                auto offset = node->data_count(bit);
882
                auto val    = node->values() + offset;
883
                if (Equal{}(*val, k))
884
                    return node_t::copy_inner_replace_value(
885
                        node,
886
                        offset,
887
                        Combine{}(std::forward<K>(k),
888
                                  std::forward<Fn>(fn)(
889
                                      Project{}(detail::as_const(*val)))));
890
                else {
891
                    return nullptr;
892
                }
893
            } else {
894
                return nullptr;
895
            }
896
        }
897
    }
898
899
    template <typename Project, typename Combine, typename K, typename Fn>
900
    champ update_if_exists(const K& k, Fn&& fn) const
901
    {
902
        auto hash = Hash{}(k);
903
        auto res  = do_update_if_exists<Project, Combine>(
904
            root, k, std::forward<Fn>(fn), hash, 0);
905
        if (res) {
906
            return {res, size};
907
        } else {
908
            return {root->inc(), size};
909
        };
910
    }
911
912
    using update_mut_result = add_mut_result;
913
914
    template <typename Project,
915
              typename Default,
916
              typename Combine,
917
              typename K,
918
              typename Fn>
919
    update_mut_result do_update_mut(edit_t e,
920
                                    node_t* node,
921
                                    K&& k,
922
                                    Fn&& fn,
923
                                    hash_t hash,
924
                                    shift_t shift) const
925
1.22M
    {
926
1.22M
        if (shift == max_shift<B>) {
927
2.24k
            auto fst = node->collisions();
928
2.24k
            auto lst = fst + node->collision_count();
929
5.02k
            for (; fst != lst; ++fst)
930
4.66k
                if (Equal{}(*fst, k)) {
931
1.88k
                    if (node->can_mutate(e)) {
932
1.68k
                        *fst = Combine{}(
933
1.68k
                            std::forward<K>(k),
934
1.68k
                            std::forward<Fn>(fn)(Project{}(std::move(*fst))));
935
1.68k
                        return {node, false, true};
936
1.68k
                    } else {
937
196
                        auto r = node_t::copy_collision_replace(
938
196
                            node,
939
196
                            fst,
940
196
                            Combine{}(std::forward<K>(k),
941
196
                                      std::forward<Fn>(fn)(
942
196
                                          Project{}(detail::as_const(*fst)))));
943
196
                        return {node_t::owned(r, e), false, false};
944
196
                    }
945
1.88k
                }
946
365
            auto v      = Combine{}(std::forward<K>(k),
947
365
                               std::forward<Fn>(fn)(Default{}()));
948
365
            auto mutate = node->can_mutate(e);
949
365
            auto r = mutate ? node_t::move_collision_insert(node, std::move(v))
950
365
                            : node_t::copy_collision_insert(node, std::move(v));
951
365
            return {node_t::owned(r, e), true, mutate};
952
1.22M
        } else {
953
1.22M
            auto idx = (hash & (mask<B> << shift)) >> shift;
954
1.22M
            auto bit = bitmap_t{1u} << idx;
955
1.22M
            if (node->nodemap() & bit) {
956
1.15M
                auto offset = node->children_count(bit);
957
1.15M
                auto child  = node->children()[offset];
958
1.15M
                if (node->can_mutate(e)) {
959
1.14M
                    auto result = do_update_mut<Project, Default, Combine>(
960
1.14M
                        e, child, k, std::forward<Fn>(fn), hash, shift + B);
961
1.14M
                    node->children()[offset] = result.node;
962
1.14M
                    if (!result.mutated && child->dec())
963
0
                        node_t::delete_deep_shift(child, shift + B);
964
1.14M
                    return {node, result.added, true};
965
1.14M
                } else {
966
5.85k
                    auto result = do_update<Project, Default, Combine>(
967
5.85k
                        child, k, std::forward<Fn>(fn), hash, shift + B);
968
5.85k
                    IMMER_TRY {
969
5.85k
                        result.node = node_t::copy_inner_replace(
970
5.85k
                            node, offset, result.node);
971
5.85k
                        node_t::owned(result.node, e);
972
5.85k
                        return {result.node, result.added, false};
973
5.85k
                    }
974
5.85k
                    IMMER_CATCH (...) {
975
0
                        node_t::delete_deep_shift(result.node, shift + B);
976
0
                        IMMER_RETHROW;
977
0
                    }
978
5.85k
                }
979
1.15M
            } else if (node->datamap() & bit) {
980
66.0k
                auto offset = node->data_count(bit);
981
66.0k
                auto val    = node->values() + offset;
982
66.0k
                if (Equal{}(*val, k)) {
983
61.2k
                    if (node->can_mutate(e)) {
984
60.1k
                        auto vals    = node->ensure_mutable_values(e);
985
60.1k
                        vals[offset] = Combine{}(std::forward<K>(k),
986
60.1k
                                                 std::forward<Fn>(fn)(Project{}(
987
60.1k
                                                     std::move(vals[offset]))));
988
60.1k
                        return {node, false, true};
989
60.1k
                    } else {
990
1.13k
                        auto r = node_t::copy_inner_replace_value(
991
1.13k
                            node,
992
1.13k
                            offset,
993
1.13k
                            Combine{}(std::forward<K>(k),
994
1.13k
                                      std::forward<Fn>(fn)(
995
1.13k
                                          Project{}(detail::as_const(*val)))));
996
1.13k
                        return {node_t::owned_values(r, e), false, false};
997
1.13k
                    }
998
61.2k
                } else {
999
4.73k
                    auto mutate        = node->can_mutate(e);
1000
4.73k
                    auto mutate_values = mutate && node->can_mutate_values(e);
1001
4.73k
                    auto hash2         = Hash{}(*val);
1002
4.73k
                    auto child         = node_t::make_merged_e(
1003
4.73k
                        e,
1004
4.73k
                        shift + B,
1005
4.73k
                        Combine{}(std::forward<K>(k),
1006
4.73k
                                  std::forward<Fn>(fn)(Default{}())),
1007
4.73k
                        hash,
1008
4.73k
                        mutate_values ? std::move(*val) : *val,
1009
4.73k
                        hash2);
1010
4.73k
                    IMMER_TRY {
1011
4.73k
                        auto r = mutate ? node_t::move_inner_replace_merged(
1012
3.51k
                                              e, node, bit, offset, child)
1013
4.73k
                                        : node_t::copy_inner_replace_merged(
1014
1.22k
                                              node, bit, offset, child);
1015
4.73k
                        return {node_t::owned_values_safe(r, e), true, mutate};
1016
4.73k
                    }
1017
4.73k
                    IMMER_CATCH (...) {
1018
0
                        node_t::delete_deep_shift(child, shift + B);
1019
0
                        IMMER_RETHROW;
1020
0
                    }
1021
4.73k
                }
1022
66.0k
            } else {
1023
5.64k
                auto mutate = node->can_mutate(e);
1024
5.64k
                auto v      = Combine{}(std::forward<K>(k),
1025
5.64k
                                   std::forward<Fn>(fn)(Default{}()));
1026
5.64k
                auto r      = mutate ? node_t::move_inner_insert_value(
1027
3.64k
                                      e, node, bit, std::move(v))
1028
5.64k
                                     : node_t::copy_inner_insert_value(
1029
1.99k
                                      node, bit, std::move(v));
1030
5.64k
                return {node_t::owned_values(r, e), true, mutate};
1031
5.64k
            }
1032
1.22M
        }
1033
1.22M
    }
1034
1035
    template <typename Project,
1036
              typename Default,
1037
              typename Combine,
1038
              typename K,
1039
              typename Fn>
1040
    void update_mut(edit_t e, const K& k, Fn&& fn)
1041
79.7k
    {
1042
79.7k
        auto hash = Hash{}(k);
1043
79.7k
        auto res  = do_update_mut<Project, Default, Combine>(
1044
79.7k
            e, root, k, std::forward<Fn>(fn), hash, 0);
1045
79.7k
        if (!res.mutated && root->dec())
1046
0
            node_t::delete_deep(root, 0);
1047
79.7k
        root = res.node;
1048
79.7k
        size += res.added ? 1 : 0;
1049
79.7k
    }
1050
1051
    struct update_if_exists_mut_result
1052
    {
1053
        node_t* node;
1054
        bool mutated;
1055
    };
1056
1057
    template <typename Project, typename Combine, typename K, typename Fn>
1058
    update_if_exists_mut_result do_update_if_exists_mut(edit_t e,
1059
                                                        node_t* node,
1060
                                                        K&& k,
1061
                                                        Fn&& fn,
1062
                                                        hash_t hash,
1063
                                                        shift_t shift) const
1064
    {
1065
        if (shift == max_shift<B>) {
1066
            auto fst = node->collisions();
1067
            auto lst = fst + node->collision_count();
1068
            for (; fst != lst; ++fst)
1069
                if (Equal{}(*fst, k)) {
1070
                    if (node->can_mutate(e)) {
1071
                        *fst = Combine{}(
1072
                            std::forward<K>(k),
1073
                            std::forward<Fn>(fn)(Project{}(std::move(*fst))));
1074
                        return {node, true};
1075
                    } else {
1076
                        auto r = node_t::copy_collision_replace(
1077
                            node,
1078
                            fst,
1079
                            Combine{}(std::forward<K>(k),
1080
                                      std::forward<Fn>(fn)(
1081
                                          Project{}(detail::as_const(*fst)))));
1082
                        return {node_t::owned(r, e), false};
1083
                    }
1084
                }
1085
            return {nullptr, false};
1086
        } else {
1087
            auto idx = (hash & (mask<B> << shift)) >> shift;
1088
            auto bit = bitmap_t{1u} << idx;
1089
            if (node->nodemap() & bit) {
1090
                auto offset = node->children_count(bit);
1091
                auto child  = node->children()[offset];
1092
                if (node->can_mutate(e)) {
1093
                    auto result = do_update_if_exists_mut<Project, Combine>(
1094
                        e, child, k, std::forward<Fn>(fn), hash, shift + B);
1095
                    if (result.node) {
1096
                        node->children()[offset] = result.node;
1097
                        if (!result.mutated && child->dec())
1098
                            node_t::delete_deep_shift(child, shift + B);
1099
                        return {node, true};
1100
                    } else {
1101
                        return {nullptr, false};
1102
                    }
1103
                } else {
1104
                    auto result = do_update_if_exists<Project, Combine>(
1105
                        child, k, std::forward<Fn>(fn), hash, shift + B);
1106
                    IMMER_TRY {
1107
                        if (result) {
1108
                            result = node_t::copy_inner_replace(
1109
                                node, offset, result);
1110
                            node_t::owned(result, e);
1111
                            return {result, false};
1112
                        } else {
1113
                            return {nullptr, false};
1114
                        }
1115
                    }
1116
                    IMMER_CATCH (...) {
1117
                        node_t::delete_deep_shift(result, shift + B);
1118
                        IMMER_RETHROW;
1119
                    }
1120
                }
1121
            } else if (node->datamap() & bit) {
1122
                auto offset = node->data_count(bit);
1123
                auto val    = node->values() + offset;
1124
                if (Equal{}(*val, k)) {
1125
                    if (node->can_mutate(e)) {
1126
                        auto vals    = node->ensure_mutable_values(e);
1127
                        vals[offset] = Combine{}(std::forward<K>(k),
1128
                                                 std::forward<Fn>(fn)(Project{}(
1129
                                                     std::move(vals[offset]))));
1130
                        return {node, true};
1131
                    } else {
1132
                        auto r = node_t::copy_inner_replace_value(
1133
                            node,
1134
                            offset,
1135
                            Combine{}(std::forward<K>(k),
1136
                                      std::forward<Fn>(fn)(
1137
                                          Project{}(detail::as_const(*val)))));
1138
                        return {node_t::owned_values(r, e), false};
1139
                    }
1140
                } else {
1141
                    return {nullptr, false};
1142
                }
1143
            } else {
1144
                return {nullptr, false};
1145
            }
1146
        }
1147
    }
1148
1149
    template <typename Project, typename Combine, typename K, typename Fn>
1150
    void update_if_exists_mut(edit_t e, const K& k, Fn&& fn)
1151
    {
1152
        auto hash = Hash{}(k);
1153
        auto res  = do_update_if_exists_mut<Project, Combine>(
1154
            e, root, k, std::forward<Fn>(fn), hash, 0);
1155
        if (res.node) {
1156
            if (!res.mutated && root->dec())
1157
                node_t::delete_deep(root, 0);
1158
            root = res.node;
1159
        }
1160
    }
1161
1162
    // basically:
1163
    //      variant<monostate_t, T*, node_t*>
1164
    // boo bad we are not using... C++17 :'(
1165
    struct sub_result
1166
    {
1167
        enum kind_t
1168
        {
1169
            nothing,
1170
            singleton,
1171
            tree
1172
        };
1173
1174
        union data_t
1175
        {
1176
            T* singleton;
1177
            node_t* tree;
1178
        };
1179
1180
        kind_t kind;
1181
        data_t data;
1182
1183
        sub_result()
1184
192k
            : kind{nothing} {};
1185
        sub_result(T* x)
1186
            : kind{singleton}
1187
2.72k
        {
1188
2.72k
            data.singleton = x;
1189
2.72k
        };
1190
        sub_result(node_t* x)
1191
            : kind{tree}
1192
99.3k
        {
1193
99.3k
            data.tree = x;
1194
99.3k
        };
1195
    };
1196
1197
    template <typename K>
1198
    sub_result
1199
    do_sub(node_t* node, const K& k, hash_t hash, shift_t shift) const
1200
305k
    {
1201
305k
        if (shift == max_shift<B>) {
1202
2.46k
            auto fst = node->collisions();
1203
2.46k
            auto lst = fst + node->collision_count();
1204
5.49k
            for (auto cur = fst; cur != lst; ++cur)
1205
4.92k
                if (Equal{}(*cur, k))
1206
1.88k
                    return node->collision_count() > 2
1207
1.88k
                               ? node_t::copy_collision_remove(node, cur)
1208
1.88k
                               : sub_result{fst + (cur == fst)};
1209
573
#if !defined(_MSC_VER)
1210
#if defined(__GNUC__) && !defined(__clang__)
1211
#pragma GCC diagnostic push
1212
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
1213
#endif
1214
573
#endif
1215
            // Apparently GCC is generating this warning sometimes when
1216
            // compiling the benchmarks. It makes however no sense at all.
1217
573
            return {};
1218
2.46k
#if !defined(_MSC_VER)
1219
#if defined(__GNUC__) && !defined(__clang__)
1220
#pragma GCC diagnostic pop
1221
#endif
1222
2.46k
#endif
1223
302k
        } else {
1224
302k
            auto idx = (hash & (mask<B> << shift)) >> shift;
1225
302k
            auto bit = bitmap_t{1u} << idx;
1226
302k
            if (node->nodemap() & bit) {
1227
285k
                auto offset = node->children_count(bit);
1228
285k
                auto result =
1229
285k
                    do_sub(node->children()[offset], k, hash, shift + B);
1230
285k
                switch (result.kind) {
1231
178k
                case sub_result::nothing:
1232
178k
                    return {};
1233
13.4k
                case sub_result::singleton:
1234
13.4k
                    return node->datamap() == 0 &&
1235
13.4k
                                   node->children_count() == 1 && shift > 0
1236
13.4k
                               ? result
1237
13.4k
                               : node_t::copy_inner_replace_inline(
1238
2.29k
                                     node, bit, offset, *result.data.singleton);
1239
93.1k
                case sub_result::tree:
1240
93.1k
                    IMMER_TRY {
1241
93.1k
                        return node_t::copy_inner_replace(
1242
93.1k
                            node, offset, result.data.tree);
1243
93.1k
                    }
1244
93.1k
                    IMMER_CATCH (...) {
1245
0
                        node_t::delete_deep_shift(result.data.tree, shift + B);
1246
0
                        IMMER_RETHROW;
1247
0
                    }
1248
285k
                }
1249
285k
            } else if (node->datamap() & bit) {
1250
11.0k
                auto offset = node->data_count(bit);
1251
11.0k
                auto val    = node->values() + offset;
1252
11.0k
                if (Equal{}(*val, k)) {
1253
4.73k
                    auto nv = node->data_count();
1254
4.73k
                    if (node->nodemap() || nv > 2)
1255
2.50k
                        return node_t::copy_inner_remove_value(
1256
2.50k
                            node, bit, offset);
1257
2.22k
                    else if (nv == 2) {
1258
2.00k
                        return shift > 0 ? sub_result{node->values() + !offset}
1259
2.00k
                                         : node_t::make_inner_n(
1260
0
                                               0,
1261
0
                                               node->datamap() & ~bit,
1262
0
                                               node->values()[!offset]);
1263
2.00k
                    } else {
1264
215
                        assert(shift == 0);
1265
0
                        return empty();
1266
215
                    }
1267
4.73k
                }
1268
11.0k
            }
1269
12.8k
            return {};
1270
302k
        }
1271
305k
    }
1272
1273
    template <typename K>
1274
    champ sub(const K& k) const
1275
18.5k
    {
1276
18.5k
        auto hash = Hash{}(k);
1277
18.5k
        auto res  = do_sub(root, k, hash, 0);
1278
18.5k
        switch (res.kind) {
1279
12.8k
        case sub_result::nothing:
1280
12.8k
            return *this;
1281
5.72k
        case sub_result::tree:
1282
5.72k
            return {res.data.tree, size - 1};
1283
0
        default:
1284
0
            IMMER_UNREACHABLE;
1285
18.5k
        }
1286
18.5k
    }
1287
1288
    struct sub_result_mut
1289
    {
1290
        using kind_t = typename sub_result::kind_t;
1291
        using data_t = typename sub_result::data_t;
1292
1293
        kind_t kind;
1294
        data_t data;
1295
        bool owned;
1296
        bool mutated;
1297
1298
        sub_result_mut(sub_result a)
1299
            : kind{a.kind}
1300
            , data{a.data}
1301
            , owned{false}
1302
            , mutated{false}
1303
1.48k
        {}
1304
        sub_result_mut(sub_result a, bool m)
1305
            : kind{a.kind}
1306
            , data{a.data}
1307
            , owned{false}
1308
            , mutated{m}
1309
        {}
1310
        sub_result_mut()
1311
            : kind{kind_t::nothing}
1312
56.9k
            , mutated{false} {};
1313
        sub_result_mut(T* x, bool m)
1314
            : kind{kind_t::singleton}
1315
            , owned{m}
1316
            , mutated{m}
1317
2.70k
        {
1318
2.70k
            data.singleton = x;
1319
2.70k
        };
1320
        sub_result_mut(T* x, bool o, bool m)
1321
            : kind{kind_t::singleton}
1322
            , owned{o}
1323
            , mutated{m}
1324
11.2k
        {
1325
11.2k
            data.singleton = x;
1326
11.2k
        };
1327
        sub_result_mut(node_t* x, bool m)
1328
            : kind{kind_t::tree}
1329
            , owned{false}
1330
            , mutated{m}
1331
110k
        {
1332
110k
            data.tree = x;
1333
110k
        };
1334
    };
1335
1336
    template <typename K>
1337
    sub_result_mut do_sub_mut(edit_t e,
1338
                              node_t* node,
1339
                              const K& k,
1340
                              hash_t hash,
1341
                              shift_t shift,
1342
                              void* store) const
1343
181k
    {
1344
181k
        auto mutate = node->can_mutate(e);
1345
181k
        if (shift == max_shift<B>) {
1346
2.25k
            auto fst = node->collisions();
1347
2.25k
            auto lst = fst + node->collision_count();
1348
5.23k
            for (auto cur = fst; cur != lst; ++cur) {
1349
4.56k
                if (Equal{}(*cur, k)) {
1350
1.57k
                    if (node->collision_count() <= 2) {
1351
596
                        if (mutate) {
1352
340
                            auto r = new (store)
1353
340
                                T{std::move(node->collisions()[cur == fst])};
1354
340
                            node_t::delete_collision(node);
1355
340
                            return sub_result_mut{r, true};
1356
340
                        } else {
1357
256
                            return sub_result_mut{fst + (cur == fst), false};
1358
256
                        }
1359
981
                    } else {
1360
981
                        auto r = mutate
1361
981
                                     ? node_t::move_collision_remove(node, cur)
1362
981
                                     : node_t::copy_collision_remove(node, cur);
1363
981
                        return {node_t::owned(r, e), mutate};
1364
981
                    }
1365
1.57k
                }
1366
4.56k
            }
1367
676
            return {};
1368
179k
        } else {
1369
179k
            auto idx = (hash & (mask<B> << shift)) >> shift;
1370
179k
            auto bit = bitmap_t{1u} << idx;
1371
179k
            if (node->nodemap() & bit) {
1372
171k
                auto offset   = node->children_count(bit);
1373
171k
                auto children = node->children();
1374
171k
                auto child    = children[offset];
1375
171k
                auto result =
1376
171k
                    mutate ? do_sub_mut(e, child, k, hash, shift + B, store)
1377
171k
                           : do_sub(child, k, hash, shift + B);
1378
171k
                switch (result.kind) {
1379
53.2k
                case sub_result::nothing:
1380
53.2k
                    return {};
1381
14.3k
                case sub_result::singleton:
1382
14.3k
                    if (node->datamap() == 0 && node->children_count() == 1 &&
1383
14.3k
                        shift > 0) {
1384
11.2k
                        if (mutate) {
1385
11.0k
                            node_t::delete_inner(node);
1386
11.0k
                            if (!result.mutated && child->dec())
1387
0
                                node_t::delete_deep_shift(child, shift + B);
1388
11.0k
                        }
1389
11.2k
                        return {result.data.singleton, result.owned, mutate};
1390
11.2k
                    } else {
1391
3.13k
                        auto r =
1392
3.13k
                            mutate ? node_t::move_inner_replace_inline(
1393
2.91k
                                         e,
1394
2.91k
                                         node,
1395
2.91k
                                         bit,
1396
2.91k
                                         offset,
1397
2.91k
                                         result.owned
1398
2.91k
                                             ? std::move(*result.data.singleton)
1399
2.91k
                                             : *result.data.singleton)
1400
3.13k
                                   : node_t::copy_inner_replace_inline(
1401
222
                                         node,
1402
222
                                         bit,
1403
222
                                         offset,
1404
222
                                         *result.data.singleton);
1405
3.13k
                        if (result.owned)
1406
1.63k
                            detail::destroy_at(result.data.singleton);
1407
3.13k
                        if (!result.mutated && mutate && child->dec())
1408
0
                            node_t::delete_deep_shift(child, shift + B);
1409
3.13k
                        return {node_t::owned_values(r, e), mutate};
1410
3.13k
                    }
1411
104k
                case sub_result::tree:
1412
104k
                    if (mutate) {
1413
103k
                        children[offset] = result.data.tree;
1414
103k
                        if (!result.mutated && child->dec())
1415
0
                            node_t::delete_deep_shift(child, shift + B);
1416
103k
                        return {node, true};
1417
103k
                    } else {
1418
472
                        IMMER_TRY {
1419
472
                            auto r = node_t::copy_inner_replace(
1420
472
                                node, offset, result.data.tree);
1421
472
                            return {node_t::owned(r, e), false};
1422
472
                        }
1423
472
                        IMMER_CATCH (...) {
1424
0
                            node_t::delete_deep_shift(result.data.tree,
1425
0
                                                      shift + B);
1426
0
                            IMMER_RETHROW;
1427
0
                        }
1428
472
                    }
1429
171k
                }
1430
171k
            } else if (node->datamap() & bit) {
1431
6.23k
                auto offset        = node->data_count(bit);
1432
6.23k
                auto val           = node->values() + offset;
1433
6.23k
                auto mutate_values = mutate && node->can_mutate_values(e);
1434
6.23k
                if (Equal{}(*val, k)) {
1435
4.65k
                    auto nv = node->data_count();
1436
4.65k
                    if (node->nodemap() || nv > 2) {
1437
2.14k
                        auto r = mutate ? node_t::move_inner_remove_value(
1438
1.90k
                                              e, node, bit, offset)
1439
2.14k
                                        : node_t::copy_inner_remove_value(
1440
235
                                              node, bit, offset);
1441
2.14k
                        return {node_t::owned_values_safe(r, e), mutate};
1442
2.51k
                    } else if (nv == 2) {
1443
2.11k
                        if (shift > 0) {
1444
2.11k
                            if (mutate_values) {
1445
1.29k
                                auto r = new (store)
1446
1.29k
                                    T{std::move(node->values()[!offset])};
1447
1.29k
                                node_t::delete_inner(node);
1448
1.29k
                                return {r, true};
1449
1.29k
                            } else {
1450
818
                                return {node->values() + !offset, false};
1451
818
                            }
1452
2.11k
                        } else {
1453
0
                            auto& v = node->values()[!offset];
1454
0
                            auto r  = node_t::make_inner_n(
1455
0
                                0,
1456
0
                                node->datamap() & ~bit,
1457
0
                                mutate_values ? std::move(v) : v);
1458
0
                            assert(!node->nodemap());
1459
0
                            if (mutate)
1460
0
                                node_t::delete_inner(node);
1461
0
                            return {node_t::owned_values(r, e), mutate};
1462
0
                        }
1463
2.11k
                    } else {
1464
403
                        assert(shift == 0);
1465
403
                        if (mutate)
1466
208
                            node_t::delete_inner(node);
1467
403
                        return {empty(), mutate};
1468
403
                    }
1469
4.65k
                }
1470
6.23k
            }
1471
3.10k
            return {};
1472
179k
        }
1473
181k
    }
1474
1475
    template <typename K>
1476
    void sub_mut(edit_t e, const K& k)
1477
11.4k
    {
1478
11.4k
        auto store = aligned_storage_for<T>{};
1479
11.4k
        auto hash  = Hash{}(k);
1480
11.4k
        auto res   = do_sub_mut(e, root, k, hash, 0, &store);
1481
11.4k
        switch (res.kind) {
1482
4.36k
        case sub_result::nothing:
1483
4.36k
            break;
1484
7.12k
        case sub_result::tree:
1485
7.12k
            if (!res.mutated && root->dec())
1486
0
                node_t::delete_deep(root, 0);
1487
7.12k
            root = res.data.tree;
1488
7.12k
            --size;
1489
7.12k
            break;
1490
0
        default:
1491
0
            IMMER_UNREACHABLE;
1492
11.4k
        }
1493
11.4k
    }
1494
1495
    template <typename Eq = Equal>
1496
    bool equals(const champ& other) const
1497
    {
1498
        return size == other.size && equals_tree<Eq>(root, other.root, 0);
1499
    }
1500
1501
    template <typename Eq>
1502
    static bool equals_tree(const node_t* a, const node_t* b, count_t depth)
1503
    {
1504
        if (a == b)
1505
            return true;
1506
        else if (depth == max_depth<B>) {
1507
            auto nv = a->collision_count();
1508
            return nv == b->collision_count() &&
1509
                   equals_collisions<Eq>(a->collisions(), b->collisions(), nv);
1510
        } else {
1511
            if (a->nodemap() != b->nodemap() || a->datamap() != b->datamap())
1512
                return false;
1513
            auto n = a->children_count();
1514
            for (auto i = count_t{}; i < n; ++i)
1515
                if (!equals_tree<Eq>(
1516
                        a->children()[i], b->children()[i], depth + 1))
1517
                    return false;
1518
            auto nv = a->data_count();
1519
            return !nv || equals_values<Eq>(a->values(), b->values(), nv);
1520
        }
1521
    }
1522
1523
    template <typename Eq>
1524
    static bool equals_values(const T* a, const T* b, count_t n)
1525
    {
1526
        return std::equal(a, a + n, b, Eq{});
1527
    }
1528
1529
    template <typename Eq>
1530
    static bool equals_collisions(const T* a, const T* b, count_t n)
1531
    {
1532
        auto ae = a + n;
1533
        auto be = b + n;
1534
        for (; a != ae; ++a) {
1535
            for (auto fst = b; fst != be; ++fst)
1536
                if (Eq{}(*a, *fst))
1537
                    goto good;
1538
            return false;
1539
        good:
1540
            continue;
1541
        }
1542
        return true;
1543
    }
1544
};
1545
1546
} // namespace hamts
1547
} // namespace detail
1548
} // namespace immer