Coverage Report

Created: 2026-05-30 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/immer/immer/detail/util.hpp
Line
Count
Source
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
13
#include <cstddef>
14
#include <memory>
15
#include <new>
16
#include <type_traits>
17
18
#include <immer/detail/type_traits.hpp>
19
20
#if defined(_MSC_VER)
21
#include <intrin.h> // for __lzcnt*
22
#endif
23
24
namespace immer {
25
namespace detail {
26
27
template <typename T>
28
const T* as_const(T* x)
29
{
30
    return x;
31
}
32
33
template <typename T>
34
const T& as_const(T& x)
35
{
36
    return x;
37
}
38
39
template <std::size_t Size, std::size_t Align>
40
struct aligned_storage
41
{
42
    struct type
43
    {
44
        alignas(Align) unsigned char data[Size];
45
    };
46
};
47
48
template <std::size_t Size, std::size_t Align>
49
using aligned_storage_t = typename aligned_storage<Size, Align>::type;
50
51
template <typename T>
52
using aligned_storage_for =
53
    typename aligned_storage<sizeof(T), alignof(T)>::type;
54
55
/*!
56
 * CRTP class that allows using the storage immediately following an instance of
57
 * the derived class to store objects of type `T` (i.e. "trailing storage").
58
 *
59
 * The class is guaranteed to be standard layout if the derived class is also
60
 * standard_layout.
61
 *
62
 * `EmptyStruct` should be set to `true` if the derived class is empty, this
63
 * allows the optimization of using the storage of the derived class as trailing
64
 * storage.
65
 */
66
template <typename Derived, typename T, bool EmptyStruct = false>
67
struct with_trailing_storage;
68
69
template <typename Derived, typename T>
70
struct alignas(alignof(T)) with_trailing_storage<Derived, T, true>
71
{
72
    using storage_type = T;
73
74
    T* get_storage_ptr()
75
8.95M
    {
76
8.95M
        check_base();
77
8.95M
        return reinterpret_cast<T*>(this);
78
8.95M
    }
79
80
    const T* get_storage_ptr() const
81
    {
82
        check_base();
83
        return reinterpret_cast<const T*>(this);
84
    }
85
86
    static constexpr size_t get_storage_offset()
87
383k
    {
88
383k
        check_base();
89
383k
        return 0;
90
383k
    }
immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::leaf_t, int, true>::get_storage_offset()
Line
Count
Source
87
383k
    {
88
383k
        check_base();
89
383k
        return 0;
90
383k
    }
Unexecuted instantiation: immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 5u>::leaf_t, int, true>::get_storage_offset()
Unexecuted instantiation: immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 6u>::leaf_t, int, true>::get_storage_offset()
91
92
private:
93
    static constexpr void check_base()
94
9.33M
    {
95
        // is_standard_layout requires that only one class in the hierarchy
96
        // contains non-static data members. Since this class contains one
97
        // member, the static_assert will only hold when the derived class is
98
        // empty.
99
9.33M
        static_assert(std::is_standard_layout<Derived>::value,
100
9.33M
                      "Please remove 'true' if the derived class is non emtpy");
101
9.33M
    }
immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::leaf_t, int, true>::check_base()
Line
Count
Source
94
9.33M
    {
95
        // is_standard_layout requires that only one class in the hierarchy
96
        // contains non-static data members. Since this class contains one
97
        // member, the static_assert will only hold when the derived class is
98
        // empty.
99
9.33M
        static_assert(std::is_standard_layout<Derived>::value,
100
9.33M
                      "Please remove 'true' if the derived class is non emtpy");
101
9.33M
    }
Unexecuted instantiation: immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 5u>::leaf_t, int, true>::check_base()
Unexecuted instantiation: immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 6u>::leaf_t, int, true>::check_base()
102
103
    // Dummy field to make the base class non-empty.
104
    char _;
105
};
106
107
template <typename Derived, typename T>
108
struct alignas(alignof(T)) with_trailing_storage<Derived, T, false>
109
{
110
    using storage_type = T;
111
112
    T* get_storage_ptr()
113
37.0M
    {
114
37.0M
        check_base();
115
37.0M
        auto* base = static_cast<Derived*>(this);
116
37.0M
        return reinterpret_cast<T*>(base + 1);
117
37.0M
    }
118
119
    const T* get_storage_ptr() const
120
    {
121
        check_base();
122
        auto* base = static_cast<const Derived*>(this);
123
        return reinterpret_cast<const T*>(base + 1);
124
    }
125
126
    static constexpr size_t get_storage_offset()
127
926k
    {
128
926k
        check_base();
129
926k
        return sizeof(Derived);
130
926k
    }
immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::inner_t, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>*, false>::get_storage_offset()
Line
Count
Source
127
926k
    {
128
926k
        check_base();
129
926k
        return sizeof(Derived);
130
926k
    }
Unexecuted instantiation: immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 5u>::inner_t, immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 5u>*, false>::get_storage_offset()
Unexecuted instantiation: immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 6u>::inner_t, immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 6u>*, false>::get_storage_offset()
131
132
private:
133
    static constexpr void check_base()
134
38.0M
    {
135
38.0M
        static_assert(std::is_standard_layout<Derived>::value &&
136
38.0M
                          !std::is_empty<Derived>::value,
137
38.0M
                      "Please add 'true' if the derived class is emtpy");
138
38.0M
    }
immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::inner_t, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>*, false>::check_base()
Line
Count
Source
134
38.0M
    {
135
38.0M
        static_assert(std::is_standard_layout<Derived>::value &&
136
38.0M
                          !std::is_empty<Derived>::value,
137
38.0M
                      "Please add 'true' if the derived class is emtpy");
138
38.0M
    }
Unexecuted instantiation: immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 5u>::inner_t, immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 5u>*, false>::check_base()
Unexecuted instantiation: immer::detail::with_trailing_storage<immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 6u>::inner_t, immer::detail::rbts::node<int, immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap, 1024ul>, immer::refcount_policy, immer::spinlock_policy, immer::no_transience_policy, false, true>, 5u, 6u>*, false>::check_base()
139
};
140
141
template <typename T>
142
T& auto_const_cast(const T& x)
143
22.4M
{
144
22.4M
    return const_cast<T&>(x);
145
22.4M
}
146
template <typename T>
147
T&& auto_const_cast(const T&& x)
148
{
149
    return const_cast<T&&>(std::move(x));
150
}
151
152
template <class T>
153
inline auto destroy_at(T* p) noexcept
154
    -> std::enable_if_t<std::is_trivially_destructible<T>::value>
155
{
156
    p->~T();
157
}
158
159
template <class T>
160
inline auto destroy_at(T* p) noexcept
161
    -> std::enable_if_t<!std::is_trivially_destructible<T>::value>
162
{
163
    p->~T();
164
}
165
166
template <typename Iter1>
167
constexpr bool can_trivially_detroy = std::is_trivially_destructible<
168
    typename std::iterator_traits<Iter1>::value_type>::value;
169
170
template <class Iter>
171
auto destroy(Iter, Iter last) noexcept
172
    -> std::enable_if_t<can_trivially_detroy<Iter>, Iter>
173
{
174
    return last;
175
}
176
template <class Iter>
177
auto destroy(Iter first, Iter last) noexcept
178
    -> std::enable_if_t<!can_trivially_detroy<Iter>, Iter>
179
{
180
    for (; first != last; ++first)
181
        detail::destroy_at(std::addressof(*first));
182
    return first;
183
}
184
185
template <class Iter, class Size>
186
auto destroy_n(Iter first, Size n) noexcept
187
    -> std::enable_if_t<can_trivially_detroy<Iter>, Iter>
188
3.97k
{
189
3.97k
    return first + n;
190
3.97k
}
std::__1::enable_if<can_trivially_detroy<int*>, int*>::type immer::detail::destroy_n<int*, unsigned int>(int*, unsigned int)
Line
Count
Source
188
3.42k
{
189
3.42k
    return first + n;
190
3.42k
}
std::__1::enable_if<can_trivially_detroy<int*>, int*>::type immer::detail::destroy_n<int*, unsigned long>(int*, unsigned long)
Line
Count
Source
188
551
{
189
551
    return first + n;
190
551
}
191
template <class Iter, class Size>
192
auto destroy_n(Iter first, Size n) noexcept
193
    -> std::enable_if_t<!can_trivially_detroy<Iter>, Iter>
194
{
195
    for (; n > 0; (void) ++first, --n)
196
        detail::destroy_at(std::addressof(*first));
197
    return first;
198
}
199
200
template <typename Iter1, typename Iter2>
201
constexpr bool can_trivially_copy =
202
    std::is_same<typename std::iterator_traits<Iter1>::value_type,
203
                 typename std::iterator_traits<Iter2>::value_type>::value &&
204
    std::is_trivially_copyable<
205
        typename std::iterator_traits<Iter1>::value_type>::value;
206
207
template <typename Iter1, typename Iter2>
208
auto uninitialized_move(Iter1 first, Iter1 last, Iter2 out) noexcept
209
    -> std::enable_if_t<can_trivially_copy<Iter1, Iter2>, Iter2>
210
2.04k
{
211
2.04k
    return std::copy(first, last, out);
212
2.04k
}
213
template <typename Iter1, typename Iter2>
214
auto uninitialized_move(Iter1 first, Iter1 last, Iter2 out)
215
    -> std::enable_if_t<!can_trivially_copy<Iter1, Iter2>, Iter2>
216
217
{
218
    using value_t = typename std::iterator_traits<Iter2>::value_type;
219
    auto current  = out;
220
    IMMER_TRY {
221
        for (; first != last; ++first, (void) ++current) {
222
            ::new (const_cast<void*>(static_cast<const volatile void*>(
223
                std::addressof(*current)))) value_t(std::move(*first));
224
        }
225
        return current;
226
    }
227
    IMMER_CATCH (...) {
228
        detail::destroy(out, current);
229
        IMMER_RETHROW;
230
    }
231
}
232
233
template <typename SourceIter, typename Sent, typename SinkIter>
234
auto uninitialized_copy(SourceIter first, Sent last, SinkIter out) noexcept
235
    -> std::enable_if_t<can_trivially_copy<SourceIter, SinkIter>, SinkIter>
236
2.96M
{
237
2.96M
    return std::copy(first, last, out);
238
2.96M
}
239
template <typename SourceIter, typename Sent, typename SinkIter>
240
auto uninitialized_copy(SourceIter first, Sent last, SinkIter out)
241
    -> std::enable_if_t<!can_trivially_copy<SourceIter, SinkIter>, SinkIter>
242
{
243
    using value_t = typename std::iterator_traits<SinkIter>::value_type;
244
    auto current  = out;
245
    IMMER_TRY {
246
        for (; first != last; ++first, (void) ++current) {
247
            ::new (const_cast<void*>(static_cast<const volatile void*>(
248
                std::addressof(*current)))) value_t(*first);
249
        }
250
        return current;
251
    }
252
    IMMER_CATCH (...) {
253
        detail::destroy(out, current);
254
        IMMER_RETHROW;
255
    }
256
}
257
258
template <typename Heap, typename T, typename... Args>
259
T* make(Args&&... args)
260
{
261
    auto ptr = Heap::allocate(sizeof(T));
262
    IMMER_TRY {
263
        return new (ptr) T(std::forward<Args>(args)...);
264
    }
265
    IMMER_CATCH (...) {
266
        Heap::deallocate(sizeof(T), ptr);
267
        IMMER_RETHROW;
268
    }
269
}
270
271
struct not_supported_t
272
{};
273
struct empty_t
274
{};
275
276
template <typename T>
277
struct exact_t
278
{
279
    T value;
280
    exact_t(T v)
281
        : value{v} {};
282
};
283
284
template <typename T>
285
inline constexpr auto clz_(T) -> not_supported_t
286
{
287
    IMMER_UNREACHABLE;
288
    return {};
289
}
290
#if defined(_MSC_VER)
291
// inline auto clz_(unsigned short x) { return __lzcnt16(x); }
292
// inline auto clz_(unsigned int x) { return __lzcnt(x); }
293
// inline auto clz_(unsigned __int64 x) { return __lzcnt64(x); }
294
#else
295
0
inline constexpr auto clz_(unsigned int x) { return __builtin_clz(x); }
296
0
inline constexpr auto clz_(unsigned long x) { return __builtin_clzl(x); }
297
0
inline constexpr auto clz_(unsigned long long x) { return __builtin_clzll(x); }
298
#endif
299
300
template <typename T>
301
inline constexpr T log2_aux(T x, T r = 0)
302
{
303
    return x <= 1 ? r : log2_aux(x >> 1, r + 1);
304
}
305
306
template <typename T>
307
inline constexpr auto log2(T x) -> std::
308
    enable_if_t<!std::is_same<decltype(clz_(x)), not_supported_t>::value, T>
309
0
{
310
0
    return x == 0 ? 0 : sizeof(std::size_t) * 8 - 1 - clz_(x);
311
0
}
312
313
template <typename T>
314
inline constexpr auto log2(T x)
315
    -> std::enable_if_t<std::is_same<decltype(clz_(x)), not_supported_t>::value,
316
                        T>
317
{
318
    return log2_aux(x);
319
}
320
321
template <typename T>
322
constexpr T ipow(T num, unsigned int pow)
323
64.8M
{
324
64.8M
    return pow == 0 ? 1 : num * ipow(num, pow - 1);
325
64.8M
}
326
327
template <bool b, typename F>
328
auto static_if(F&& f) -> std::enable_if_t<b>
329
875k
{
330
875k
    std::forward<F>(f)(empty_t{});
331
875k
}
Unexecuted instantiation: std::__1::enable_if<true, void>::type immer::detail::static_if<true, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::delete_inner_r(immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>*, unsigned int)::{lambda(auto:1)#1}>(immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::delete_inner_r(immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>*, unsigned int)::{lambda(auto:1)#1}&&)
std::__1::enable_if<true, void>::type immer::detail::static_if<true, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::make_inner_r_e(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit)::{lambda(auto:1)#1}>(immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::make_inner_r_e(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit)::{lambda(auto:1)#1}&&)
Line
Count
Source
329
875k
{
330
875k
    std::forward<F>(f)(empty_t{});
331
875k
}
Unexecuted instantiation: std::__1::enable_if<true, void>::type immer::detail::static_if<true, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::delete_inner_r_e(immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>*)::{lambda(auto:1)#1}>(immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::delete_inner_r_e(immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>*)::{lambda(auto:1)#1}&&)
332
template <bool b, typename F>
333
auto static_if(F&& f) -> std::enable_if_t<!b>
334
{
335
}
336
337
template <bool b, typename R = void, typename F1, typename F2>
338
auto static_if(F1&& f1, F2&& f2) -> std::enable_if_t<b, R>
339
{
340
    return std::forward<F1>(f1)(empty_t{});
341
}
342
template <bool b, typename R = void, typename F1, typename F2>
343
auto static_if(F1&& f1, F2&& f2) -> std::enable_if_t<!b, R>
344
1.49M
{
345
1.49M
    return std::forward<F2>(f2)(empty_t{});
346
1.49M
}
std::__1::enable_if<!(false), immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>*>::type immer::detail::static_if<false, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>*, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::make_inner_sr_n(unsigned int, immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*)::{lambda(auto:1)#1}, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::make_inner_sr_n(unsigned int, immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*)::{lambda(auto:1)#2}>(immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::make_inner_sr_n(unsigned int, immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*)::{lambda(auto:1)#1}&&, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::make_inner_sr_n(unsigned int, immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*)::{lambda(auto:1)#2}&&)
Line
Count
Source
344
30.1k
{
345
30.1k
    return std::forward<F2>(f2)(empty_t{});
346
30.1k
}
std::__1::enable_if<!(false), immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*>::type immer::detail::static_if<false, immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::ensure_mutable_relaxed_n(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, unsigned int)::{lambda(auto:1)#1}, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::ensure_mutable_relaxed_n(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, unsigned int)::{lambda(auto:1)#2}>(immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::ensure_mutable_relaxed_n(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, unsigned int)::{lambda(auto:1)#1}&&, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::ensure_mutable_relaxed_n(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, unsigned int)::{lambda(auto:1)#2}&&)
Line
Count
Source
344
894k
{
345
894k
    return std::forward<F2>(f2)(empty_t{});
346
894k
}
std::__1::enable_if<!(false), immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>*>::type immer::detail::static_if<false, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>*, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::make_inner_sr_e(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*)::{lambda(auto:1)#1}, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::make_inner_sr_e(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*)::{lambda(auto:1)#2}>(immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::make_inner_sr_e(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*)::{lambda(auto:1)#1}&&, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::make_inner_sr_e(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*)::{lambda(auto:1)#2}&&)
Line
Count
Source
344
18.9k
{
345
18.9k
    return std::forward<F2>(f2)(empty_t{});
346
18.9k
}
std::__1::enable_if<!(false), immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*>::type immer::detail::static_if<false, immer::detail::csl::member_two<immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::relaxed_data_t, immer::detail::csl::inherit<immer::no_refcount_policy, immer::detail::csl::member<immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::ownee, void>::type>::type>::type*, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::ensure_mutable_relaxed_e(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit)::{lambda(auto:1)#1}, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::ensure_mutable_relaxed_e(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit)::{lambda(auto:1)#2}>(immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::ensure_mutable_relaxed_e(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit)::{lambda(auto:1)#1}&&, immer::detail::rbts::node<int, immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::spinlock_policy, immer::gc_transience_policy, false, false>, 2u, 2u>::ensure_mutable_relaxed_e(immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit, immer::gc_transience_policy::apply<immer::heap_policy<immer::gc_heap> >::type::edit)::{lambda(auto:1)#2}&&)
Line
Count
Source
344
555k
{
345
555k
    return std::forward<F2>(f2)(empty_t{});
346
555k
}
347
348
template <typename T, T value>
349
struct constantly
350
{
351
    template <typename... Args>
352
    T operator()(Args&&...) const
353
    {
354
        return value;
355
    }
356
};
357
358
/*!
359
 * An alias to `std::distance`
360
 */
361
template <typename Iterator,
362
          typename Sentinel,
363
          std::enable_if_t<detail::std_distance_supports_v<Iterator, Sentinel>,
364
                           bool> = true>
365
typename std::iterator_traits<Iterator>::difference_type
366
distance(Iterator first, Sentinel last)
367
{
368
    return std::distance(first, last);
369
}
370
371
/*!
372
 * Equivalent of the `std::distance` applied to the sentinel-delimited
373
 * forward range @f$ [first, last) @f$
374
 */
375
template <typename Iterator,
376
    typename Sentinel,
377
          std::enable_if_t<
378
              (!detail::std_distance_supports_v<Iterator, Sentinel>) &&detail::
379
                      is_forward_iterator_v<Iterator> &&
380
                         detail::compatible_sentinel_v<Iterator, Sentinel> &&
381
                         (!detail::is_subtractable_v<Sentinel, Iterator>),
382
                     bool> = true>
383
typename std::iterator_traits<Iterator>::difference_type
384
distance(Iterator first, Sentinel last)
385
{
386
    std::size_t result = 0;
387
    while (first != last) {
388
        ++first;
389
        ++result;
390
    }
391
    return result;
392
}
393
394
/*!
395
 * Equivalent of the `std::distance` applied to the sentinel-delimited
396
 * random access range @f$ [first, last) @f$
397
 */
398
template <typename Iterator,
399
    typename Sentinel,
400
          std::enable_if_t<
401
              (!detail::std_distance_supports_v<Iterator, Sentinel>) &&detail::
402
                      is_forward_iterator_v<Iterator> &&
403
                         detail::compatible_sentinel_v<Iterator, Sentinel> &&
404
                         detail::is_subtractable_v<Sentinel, Iterator>,
405
                     bool> = true>
406
typename std::iterator_traits<Iterator>::difference_type
407
distance(Iterator first, Sentinel last)
408
{
409
    return last - first;
410
}
411
412
} // namespace detail
413
} // namespace immer