Line | Count | Source |
1 | | // Copyright (c) 2018-present The Bitcoin Core developers |
2 | | // Distributed under the MIT software license, see the accompanying |
3 | | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
4 | | |
5 | | #ifndef BITCOIN_SPAN_H |
6 | | #define BITCOIN_SPAN_H |
7 | | |
8 | | #include <cassert> |
9 | | #include <cstddef> |
10 | | #include <span> |
11 | | #include <type_traits> |
12 | | #include <utility> |
13 | | |
14 | | /** A span is an object that can refer to a contiguous sequence of objects. |
15 | | * |
16 | | * Things to be aware of when writing code that deals with spans: |
17 | | * |
18 | | * - Similar to references themselves, spans are subject to reference lifetime |
19 | | * issues. The user is responsible for making sure the objects pointed to by |
20 | | * a span live as long as the span is used. For example: |
21 | | * |
22 | | * std::vector<int> vec{1,2,3,4}; |
23 | | * std::span<int> sp(vec); |
24 | | * vec.push_back(5); |
25 | | * printf("%i\n", sp.front()); // UB! |
26 | | * |
27 | | * may exhibit undefined behavior, as increasing the size of a vector may |
28 | | * invalidate references. |
29 | | * |
30 | | * - One particular pitfall is that spans can be constructed from temporaries, |
31 | | * but this is unsafe when the span is stored in a variable, outliving the |
32 | | * temporary. For example, this will compile, but exhibits undefined behavior: |
33 | | * |
34 | | * std::span<const int> sp(std::vector<int>{1, 2, 3}); |
35 | | * printf("%i\n", sp.front()); // UB! |
36 | | * |
37 | | * The lifetime of the vector ends when the statement it is created in ends. |
38 | | * Thus the span is left with a dangling reference, and using it is undefined. |
39 | | * |
40 | | * - Due to spans automatic creation from range-like objects (arrays, and data |
41 | | * types that expose a data() and size() member function), functions that |
42 | | * accept a span as input parameter can be called with any compatible |
43 | | * range-like object. For example, this works: |
44 | | * |
45 | | * void Foo(std::span<const int> arg); |
46 | | * |
47 | | * Foo(std::vector<int>{1, 2, 3}); // Works |
48 | | * |
49 | | * This is very useful in cases where a function truly does not care about the |
50 | | * container, and only about having exactly a range of elements. However it |
51 | | * may also be surprising to see automatic conversions in this case. |
52 | | * |
53 | | * When a function accepts a span with a mutable element type, it will not |
54 | | * accept temporaries; only variables or other references. For example: |
55 | | * |
56 | | * void FooMut(std::span<int> arg); |
57 | | * |
58 | | * FooMut(std::vector<int>{1, 2, 3}); // Does not compile |
59 | | * std::vector<int> baz{1, 2, 3}; |
60 | | * FooMut(baz); // Works |
61 | | * |
62 | | * This is similar to how functions that take (non-const) lvalue references |
63 | | * as input cannot accept temporaries. This does not work either: |
64 | | * |
65 | | * void FooVec(std::vector<int>& arg); |
66 | | * FooVec(std::vector<int>{1, 2, 3}); // Does not compile |
67 | | * |
68 | | * The idea is that if a function accepts a mutable reference, a meaningful |
69 | | * result will be present in that variable after the call. Passing a temporary |
70 | | * is useless in that context. |
71 | | */ |
72 | | |
73 | | /** Pop the last element off a span, and return a reference to that element. */ |
74 | | template <typename T> |
75 | | T& SpanPopBack(std::span<T>& span) |
76 | 476k | { |
77 | 476k | size_t size = span.size(); |
78 | 476k | T& back = span.back(); |
79 | 476k | span = span.first(size - 1); |
80 | 476k | return back; |
81 | 476k | } std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const& SpanPopBack<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const>(std::span<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, 18446744073709551615ul>&) Line | Count | Source | 76 | 2 | { | 77 | 2 | size_t size = span.size(); | 78 | 2 | T& back = span.back(); | 79 | 2 | span = span.first(size - 1); | 80 | 2 | return back; | 81 | 2 | } |
std::vector<unsigned char, std::allocator<unsigned char>> const& SpanPopBack<std::vector<unsigned char, std::allocator<unsigned char>> const>(std::span<std::vector<unsigned char, std::allocator<unsigned char>> const, 18446744073709551615ul>&) Line | Count | Source | 76 | 290k | { | 77 | 290k | size_t size = span.size(); | 78 | 290k | T& back = span.back(); | 79 | 290k | span = span.first(size - 1); | 80 | 290k | return back; | 81 | 290k | } |
unsigned char const& SpanPopBack<unsigned char const>(std::span<unsigned char const, 18446744073709551615ul>&) Line | Count | Source | 76 | 185k | { | 77 | 185k | size_t size = span.size(); | 78 | 185k | T& back = span.back(); | 79 | 185k | span = span.first(size - 1); | 80 | 185k | return back; | 81 | 185k | } |
|
82 | | |
83 | | template <typename V> |
84 | | auto MakeByteSpan(const V& v) noexcept |
85 | 33.7M | { |
86 | 33.7M | return std::as_bytes(std::span{v}); |
87 | 33.7M | } auto MakeByteSpan<std::array<unsigned char, 4ul>>(std::array<unsigned char, 4ul> const&) Line | Count | Source | 85 | 368k | { | 86 | 368k | return std::as_bytes(std::span{v}); | 87 | 368k | } |
auto MakeByteSpan<prevector<16u, unsigned char, unsigned int, int>>(prevector<16u, unsigned char, unsigned int, int> const&) Line | Count | Source | 85 | 100k | { | 86 | 100k | return std::as_bytes(std::span{v}); | 87 | 100k | } |
auto MakeByteSpan<unsigned char [16]>(unsigned char const (&) [16]) Line | Count | Source | 85 | 22.0k | { | 86 | 22.0k | return std::as_bytes(std::span{v}); | 87 | 22.0k | } |
auto MakeByteSpan<std::vector<std::byte, std::allocator<std::byte>>>(std::vector<std::byte, std::allocator<std::byte>> const&) Line | Count | Source | 85 | 1.50k | { | 86 | 1.50k | return std::as_bytes(std::span{v}); | 87 | 1.50k | } |
auto MakeByteSpan<prevector<36u, unsigned char, unsigned int, int>>(prevector<36u, unsigned char, unsigned int, int> const&) Line | Count | Source | 85 | 25.5M | { | 86 | 25.5M | return std::as_bytes(std::span{v}); | 87 | 25.5M | } |
auto MakeByteSpan<std::vector<unsigned char, std::allocator<unsigned char>>>(std::vector<unsigned char, std::allocator<unsigned char>> const&) Line | Count | Source | 85 | 3.85M | { | 86 | 3.85M | return std::as_bytes(std::span{v}); | 87 | 3.85M | } |
auto MakeByteSpan<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) Line | Count | Source | 85 | 591k | { | 86 | 591k | return std::as_bytes(std::span{v}); | 87 | 591k | } |
auto MakeByteSpan<uint256>(uint256 const&) Line | Count | Source | 85 | 1.90M | { | 86 | 1.90M | return std::as_bytes(std::span{v}); | 87 | 1.90M | } |
auto MakeByteSpan<std::span<unsigned char, 18446744073709551615ul>>(std::span<unsigned char, 18446744073709551615ul> const&) Line | Count | Source | 85 | 158k | { | 86 | 158k | return std::as_bytes(std::span{v}); | 87 | 158k | } |
auto MakeByteSpan<std::span<unsigned char const, 18446744073709551615ul>>(std::span<unsigned char const, 18446744073709551615ul> const&) Line | Count | Source | 85 | 108k | { | 86 | 108k | return std::as_bytes(std::span{v}); | 87 | 108k | } |
auto MakeByteSpan<char [12]>(char const (&) [12]) Line | Count | Source | 85 | 160k | { | 86 | 160k | return std::as_bytes(std::span{v}); | 87 | 160k | } |
auto MakeByteSpan<unsigned char [4]>(unsigned char const (&) [4]) Line | Count | Source | 85 | 164k | { | 86 | 164k | return std::as_bytes(std::span{v}); | 87 | 164k | } |
auto MakeByteSpan<std::array<std::byte, 6ul>>(std::array<std::byte, 6ul> const&) Line | Count | Source | 85 | 3 | { | 86 | 3 | return std::as_bytes(std::span{v}); | 87 | 3 | } |
auto MakeByteSpan<std::array<std::byte, 4ul>>(std::array<std::byte, 4ul> const&) Line | Count | Source | 85 | 1 | { | 86 | 1 | return std::as_bytes(std::span{v}); | 87 | 1 | } |
auto MakeByteSpan<std::array<std::byte, 8ul>>(std::array<std::byte, 8ul> const&) Line | Count | Source | 85 | 441 | { | 86 | 441 | return std::as_bytes(std::span{v}); | 87 | 441 | } |
auto MakeByteSpan<std::array<std::byte, 18ul>>(std::array<std::byte, 18ul> const&) Line | Count | Source | 85 | 6 | { | 86 | 6 | return std::as_bytes(std::span{v}); | 87 | 6 | } |
auto MakeByteSpan<std::array<std::byte, 3ul>>(std::array<std::byte, 3ul> const&) Line | Count | Source | 85 | 4 | { | 86 | 4 | return std::as_bytes(std::span{v}); | 87 | 4 | } |
auto MakeByteSpan<std::array<std::byte, 12ul>>(std::array<std::byte, 12ul> const&) Line | Count | Source | 85 | 1 | { | 86 | 1 | return std::as_bytes(std::span{v}); | 87 | 1 | } |
auto MakeByteSpan<std::array<std::byte, 34ul>>(std::array<std::byte, 34ul> const&) Line | Count | Source | 85 | 2 | { | 86 | 2 | return std::as_bytes(std::span{v}); | 87 | 2 | } |
auto MakeByteSpan<std::array<std::byte, 13ul>>(std::array<std::byte, 13ul> const&) Line | Count | Source | 85 | 1 | { | 86 | 1 | return std::as_bytes(std::span{v}); | 87 | 1 | } |
auto MakeByteSpan<std::array<std::byte, 2ul>>(std::array<std::byte, 2ul> const&) Line | Count | Source | 85 | 1 | { | 86 | 1 | return std::as_bytes(std::span{v}); | 87 | 1 | } |
auto MakeByteSpan<std::basic_string_view<char, std::char_traits<char>>>(std::basic_string_view<char, std::char_traits<char>> const&) Line | Count | Source | 85 | 1 | { | 86 | 1 | return std::as_bytes(std::span{v}); | 87 | 1 | } |
auto MakeByteSpan<std::array<unsigned char, 1ul>>(std::array<unsigned char, 1ul> const&) Line | Count | Source | 85 | 1 | { | 86 | 1 | return std::as_bytes(std::span{v}); | 87 | 1 | } |
auto MakeByteSpan<std::array<unsigned char, 2ul>>(std::array<unsigned char, 2ul> const&) Line | Count | Source | 85 | 1 | { | 86 | 1 | return std::as_bytes(std::span{v}); | 87 | 1 | } |
auto MakeByteSpan<std::array<unsigned char, 32ul>>(std::array<unsigned char, 32ul> const&) Line | Count | Source | 85 | 1 | { | 86 | 1 | return std::as_bytes(std::span{v}); | 87 | 1 | } |
auto MakeByteSpan<char [16]>(char const (&) [16]) Line | Count | Source | 85 | 2 | { | 86 | 2 | return std::as_bytes(std::span{v}); | 87 | 2 | } |
auto MakeByteSpan<unsigned char [5]>(unsigned char const (&) [5]) Line | Count | Source | 85 | 864 | { | 86 | 864 | return std::as_bytes(std::span{v}); | 87 | 864 | } |
Unexecuted instantiation: auto MakeByteSpan<unsigned char [78]>(unsigned char const (&) [78]) auto MakeByteSpan<leveldb::Slice>(leveldb::Slice const&) Line | Count | Source | 85 | 715k | { | 86 | 715k | return std::as_bytes(std::span{v}); | 87 | 715k | } |
auto MakeByteSpan<char [1]>(char const (&) [1]) Line | Count | Source | 85 | 38 | { | 86 | 38 | return std::as_bytes(std::span{v}); | 87 | 38 | } |
Unexecuted instantiation: auto MakeByteSpan<std::array<std::byte, 168ul>>(std::array<std::byte, 168ul> const&) auto MakeByteSpan<std::array<unsigned char, 5ul>>(std::array<unsigned char, 5ul> const&) Line | Count | Source | 85 | 44 | { | 86 | 44 | return std::as_bytes(std::span{v}); | 87 | 44 | } |
auto MakeByteSpan<std::vector<unsigned char, secure_allocator<unsigned char>>>(std::vector<unsigned char, secure_allocator<unsigned char>> const&) Line | Count | Source | 85 | 4.24k | { | 86 | 4.24k | return std::as_bytes(std::span{v}); | 87 | 4.24k | } |
auto MakeByteSpan<unsigned char [384]>(unsigned char const (&) [384]) Line | Count | Source | 85 | 4.09k | { | 86 | 4.09k | return std::as_bytes(std::span{v}); | 87 | 4.09k | } |
|
88 | | template <typename V> |
89 | | auto MakeWritableByteSpan(V&& v) noexcept |
90 | 13.5M | { |
91 | 13.5M | return std::as_writable_bytes(std::span{std::forward<V>(v)}); |
92 | 13.5M | } auto MakeWritableByteSpan<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) Line | Count | Source | 90 | 168k | { | 91 | 168k | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 168k | } |
auto MakeWritableByteSpan<uint256&>(uint256&) Line | Count | Source | 90 | 1.30M | { | 91 | 1.30M | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 1.30M | } |
auto MakeWritableByteSpan<unsigned char (&) [4]>(unsigned char (&) [4]) Line | Count | Source | 90 | 160k | { | 91 | 160k | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 160k | } |
auto MakeWritableByteSpan<std::array<unsigned char, 32ul>&>(std::array<unsigned char, 32ul>&) Line | Count | Source | 90 | 2.95M | { | 91 | 2.95M | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 2.95M | } |
auto MakeWritableByteSpan<std::vector<unsigned char, std::allocator<unsigned char>>&>(std::vector<unsigned char, std::allocator<unsigned char>>&) Line | Count | Source | 90 | 126k | { | 91 | 126k | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 126k | } |
auto MakeWritableByteSpan<unsigned char (&) [16]>(unsigned char (&) [16]) Line | Count | Source | 90 | 7.53k | { | 91 | 7.53k | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 7.53k | } |
auto MakeWritableByteSpan<std::vector<std::byte, std::allocator<std::byte>>&>(std::vector<std::byte, std::allocator<std::byte>>&) Line | Count | Source | 90 | 104 | { | 91 | 104 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 104 | } |
auto MakeWritableByteSpan<std::array<std::byte, 17ul>&>(std::array<std::byte, 17ul>&) Line | Count | Source | 90 | 1 | { | 91 | 1 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 1 | } |
auto MakeWritableByteSpan<char (&) [16]>(char (&) [16]) Line | Count | Source | 90 | 3 | { | 91 | 3 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 3 | } |
auto MakeWritableByteSpan<std::array<std::byte, 8ul>&>(std::array<std::byte, 8ul>&) Line | Count | Source | 90 | 2.22k | { | 91 | 2.22k | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 2.22k | } |
auto MakeWritableByteSpan<unsigned char (&) [29]>(unsigned char (&) [29]) Line | Count | Source | 90 | 1 | { | 91 | 1 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 1 | } |
auto MakeWritableByteSpan<unsigned char (&) [1]>(unsigned char (&) [1]) Line | Count | Source | 90 | 644 | { | 91 | 644 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 644 | } |
auto MakeWritableByteSpan<unsigned char (&) [2]>(unsigned char (&) [2]) Line | Count | Source | 90 | 635 | { | 91 | 635 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 635 | } |
auto MakeWritableByteSpan<unsigned char (&) [5]>(unsigned char (&) [5]) Line | Count | Source | 90 | 1.97k | { | 91 | 1.97k | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 1.97k | } |
auto MakeWritableByteSpan<std::array<unsigned char, 20ul>&>(std::array<unsigned char, 20ul>&) Line | Count | Source | 90 | 395 | { | 91 | 395 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 395 | } |
auto MakeWritableByteSpan<std::array<unsigned char, 2ul>&>(std::array<unsigned char, 2ul>&) Line | Count | Source | 90 | 2 | { | 91 | 2 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 2 | } |
auto MakeWritableByteSpan<std::array<unsigned char, 5ul>&>(std::array<unsigned char, 5ul>&) Line | Count | Source | 90 | 73 | { | 91 | 73 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 73 | } |
auto MakeWritableByteSpan<std::array<unsigned char, 4ul>&>(std::array<unsigned char, 4ul>&) Line | Count | Source | 90 | 8.69M | { | 91 | 8.69M | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 8.69M | } |
auto MakeWritableByteSpan<char (&) [12]>(char (&) [12]) Line | Count | Source | 90 | 152k | { | 91 | 152k | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 152k | } |
auto MakeWritableByteSpan<std::array<std::byte, 20ul>&>(std::array<std::byte, 20ul>&) Line | Count | Source | 90 | 92 | { | 91 | 92 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 92 | } |
auto MakeWritableByteSpan<char (&) [368]>(char (&) [368]) Line | Count | Source | 90 | 92 | { | 91 | 92 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 92 | } |
auto MakeWritableByteSpan<unsigned char (&) [20]>(unsigned char (&) [20]) Line | Count | Source | 90 | 92 | { | 91 | 92 | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 92 | } |
auto MakeWritableByteSpan<unsigned char (&) [384]>(unsigned char (&) [384]) Line | Count | Source | 90 | 6.05k | { | 91 | 6.05k | return std::as_writable_bytes(std::span{std::forward<V>(v)}); | 92 | 6.05k | } |
|
93 | | |
94 | | // Helper functions to safely cast basic byte pointers to unsigned char pointers. |
95 | 2.18k | inline unsigned char* UCharCast(char* c) { return reinterpret_cast<unsigned char*>(c); } |
96 | 32.2k | inline unsigned char* UCharCast(unsigned char* c) { return c; } |
97 | 0 | inline unsigned char* UCharCast(signed char* c) { return reinterpret_cast<unsigned char*>(c); } |
98 | 2.18M | inline unsigned char* UCharCast(std::byte* c) { return reinterpret_cast<unsigned char*>(c); } |
99 | 398k | inline const unsigned char* UCharCast(const char* c) { return reinterpret_cast<const unsigned char*>(c); } |
100 | 9.31M | inline const unsigned char* UCharCast(const unsigned char* c) { return c; } |
101 | 0 | inline const unsigned char* UCharCast(const signed char* c) { return reinterpret_cast<const unsigned char*>(c); } |
102 | 365M | inline const unsigned char* UCharCast(const std::byte* c) { return reinterpret_cast<const unsigned char*>(c); } |
103 | | // Helper concept for the basic byte types. |
104 | | template <typename B> |
105 | | concept BasicByte = requires { UCharCast(std::span<B>{}.data()); }; |
106 | | |
107 | | // Helper function to safely convert a span to a span<[const] unsigned char>. |
108 | 8.25M | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; }auto UCharSpanCast<char const, 18446744073709551615ul>(std::span<char const, 18446744073709551615ul>) Line | Count | Source | 108 | 57.2k | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<std::byte const, 18446744073709551615ul>(std::span<std::byte const, 18446744073709551615ul>) Line | Count | Source | 108 | 82.7k | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<unsigned char const, 18446744073709551615ul>(std::span<unsigned char const, 18446744073709551615ul>) Line | Count | Source | 108 | 8.08M | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<std::byte const, 4ul>(std::span<std::byte const, 4ul>) Line | Count | Source | 108 | 7 | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<std::byte const, 8ul>(std::span<std::byte const, 8ul>) Line | Count | Source | 108 | 4 | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<std::byte const, 1ul>(std::span<std::byte const, 1ul>) Line | Count | Source | 108 | 6 | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<std::byte const, 5ul>(std::span<std::byte const, 5ul>) Line | Count | Source | 108 | 2 | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<std::byte const, 3ul>(std::span<std::byte const, 3ul>) Line | Count | Source | 108 | 7 | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<std::byte const, 7ul>(std::span<std::byte const, 7ul>) Line | Count | Source | 108 | 2 | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<std::byte const, 25ul>(std::span<std::byte const, 25ul>) Line | Count | Source | 108 | 2 | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<std::byte const, 65ul>(std::span<std::byte const, 65ul>) Line | Count | Source | 108 | 2 | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<unsigned char, 18446744073709551615ul>(std::span<unsigned char, 18446744073709551615ul>) Line | Count | Source | 108 | 26.8k | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
auto UCharSpanCast<unsigned char const, 8ul>(std::span<unsigned char const, 8ul>) Line | Count | Source | 108 | 4.55k | template <typename T, size_t N> constexpr auto UCharSpanCast(std::span<T, N> s) { return std::span<std::remove_pointer_t<decltype(UCharCast(s.data()))>, N>{UCharCast(s.data()), s.size()}; } |
|
109 | | |
110 | | /** Like the std::span constructor, but for (const) unsigned char member types only. Only works for (un)signed char containers. */ |
111 | 8.25M | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); }decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::span<char const, 18446744073709551615ul>>(std::span<char const, 18446744073709551615ul> const&)Line | Count | Source | 111 | 52 | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::span<std::byte const, 18446744073709551615ul>>(std::span<std::byte const, 18446744073709551615ul> const&)Line | Count | Source | 111 | 73.0k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::basic_string_view<char, std::char_traits<char>>>(std::basic_string_view<char, std::char_traits<char>> const&)Line | Count | Source | 111 | 2.05k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::span<unsigned char const, 18446744073709551615ul>>(std::span<unsigned char const, 18446744073709551615ul> const&)Line | Count | Source | 111 | 5.66M | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)Line | Count | Source | 111 | 55.1k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<uint256>(uint256 const&)Line | Count | Source | 111 | 1.73M | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<XOnlyPubKey>(XOnlyPubKey const&)Line | Count | Source | 111 | 13.1k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::vector<std::byte, std::allocator<std::byte>>>(std::vector<std::byte, std::allocator<std::byte>> const&)Line | Count | Source | 111 | 3.73k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::vector<unsigned char, std::allocator<unsigned char>>>(std::vector<unsigned char, std::allocator<unsigned char>> const&)Line | Count | Source | 111 | 366k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::array<std::byte, 4ul>>(std::array<std::byte, 4ul> const&)Line | Count | Source | 111 | 7 | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::array<std::byte, 8ul>>(std::array<std::byte, 8ul> const&)Line | Count | Source | 111 | 4 | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::array<std::byte, 1ul>>(std::array<std::byte, 1ul> const&)Line | Count | Source | 111 | 6 | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::array<std::byte, 5ul>>(std::array<std::byte, 5ul> const&)Line | Count | Source | 111 | 2 | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::array<std::byte, 3ul>>(std::array<std::byte, 3ul> const&)Line | Count | Source | 111 | 7 | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::array<std::byte, 7ul>>(std::array<std::byte, 7ul> const&)Line | Count | Source | 111 | 2 | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::array<std::byte, 25ul>>(std::array<std::byte, 25ul> const&)Line | Count | Source | 111 | 2 | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<DataStream>(DataStream const&)Line | Count | Source | 111 | 5.97k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::array<std::byte, 65ul>>(std::array<std::byte, 65ul> const&)Line | Count | Source | 111 | 2 | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<CPubKey>(CPubKey const&)Line | Count | Source | 111 | 6.64k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<CScript>(CScript const&)Line | Count | Source | 111 | 290k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::vector<unsigned char, secure_allocator<unsigned char>>>(std::vector<unsigned char, secure_allocator<unsigned char>> const&)Line | Count | Source | 111 | 6.64k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<std::span<unsigned char, 18446744073709551615ul>>(std::span<unsigned char, 18446744073709551615ul> const&)Line | Count | Source | 111 | 26.8k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
decltype(UCharSpanCast(std::span{fp})) MakeUCharSpan<unsigned char [8]>(unsigned char const (&) [8])Line | Count | Source | 111 | 4.55k | template <typename V> constexpr auto MakeUCharSpan(const V& v) -> decltype(UCharSpanCast(std::span{v})) { return UCharSpanCast(std::span{v}); } |
|
112 | | template <typename V> constexpr auto MakeWritableUCharSpan(V&& v) -> decltype(UCharSpanCast(std::span{std::forward<V>(v)})) { return UCharSpanCast(std::span{std::forward<V>(v)}); } |
113 | | |
114 | | #endif // BITCOIN_SPAN_H |