/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&&) constLine  | 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&&) constLine  | 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&&) constLine  | 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&&) constLine  | 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&&) constLine  | 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&&) constLine  | 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&&) constLine  | 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&&) constLine  | 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&&) constLine  | 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&&) constLine  | 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&&) constLine  | 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&&) constLine  | 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) constLine  | 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) constLine  | 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) constLine  | 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) constLine  | 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}) constLine  | 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}) constLine  | 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) constLine  | 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) constLine  | 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  |