• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

libbitcoin / libbitcoin-system / 13025432554

29 Jan 2025 05:52AM UTC coverage: 82.735% (+0.1%) from 82.637%
13025432554

push

github

web-flow
Merge pull request #1602 from pmienk/master

Regenerate artifacts.

10049 of 12146 relevant lines covered (82.74%)

3868132.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.5
/include/bitcoin/system/impl/data/array_cast.ipp
1
/**
2
 * Copyright (c) 2011-2025 libbitcoin developers (see AUTHORS)
3
 *
4
 * This file is part of libbitcoin.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Affero General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
#ifndef LIBBITCOIN_SYSTEM_DATA_ARRAY_CAST_IPP
20
#define LIBBITCOIN_SYSTEM_DATA_ARRAY_CAST_IPP
21

22
#include <iterator>
23
#include <utility>
24
#include <bitcoin/system/define.hpp>
25
#include <bitcoin/system/math/math.hpp>
26

27
namespace libbitcoin {
28
namespace system {
29

30
// Sequence generation.
31
// ----------------------------------------------------------------------------
32

33
// Suppress bogus warnings to use constexpr when function is consteval.
34
BC_PUSH_WARNING(USE_CONSTEXPR_FOR_FUNCTION)
35

36
// Helper to extract Index parameter pack from std::make_index_sequence<Size>.
37
template<typename Integer, size_t Size, size_t... Index>
38
CONSTEVAL auto to_array(std::index_sequence<Index...>) NOEXCEPT
39
{
40
    return std_array<Integer, Size>{ { Index... } };
41
}
42

43
template<typename Integer, size_t Size>
44
CONSTEVAL std_array<Integer, Size> to_sequence() NOEXCEPT
45
{
46
    return to_array<Integer, Size>(std::make_index_sequence<Size>{});
47
}
48

49
BC_POP_WARNING()
50

51
// Array casting helpers.
52
// ----------------------------------------------------------------------------
53
    
54
template <typename To, typename From>
55
constexpr bool is_portional(size_t to_count, size_t from_count) NOEXCEPT
56
{
57
    // Guards against the protion being greater than available.
58
    return !is_multiply_overflow(to_count, size_of<To>())
59
        && !is_multiply_overflow(from_count, size_of<From>())
60
        && (to_count * size_of<To>() <= from_count * size_of<From>());
61
}
62

63
template <typename From, typename To>
64
constexpr bool is_proportional(size_t from_count) NOEXCEPT
65
{
66
    return !is_multiply_overflow(from_count, size_of<From>())
67
        && is_multiple(from_count * size_of<From>(), size_of<To>());
68
}
69

70
// Cast array(T1) to same-sized array(T2).
71
// ----------------------------------------------------------------------------
72

73
template <typename To, size_t Count, typename From>
74
inline std_array<To, proportion<Count, From, To>>&
75
array_cast(std_array<From, Count>& values) NOEXCEPT
16,522✔
76
{
77
    using to = std_array<To, proportion<Count, From, To>>;
78
    return *pointer_cast<to>(values.data());
×
79
}
80

81
template <typename To, size_t Count, typename From>
82
inline const std_array<To, proportion<Count, From, To>>&
83
array_cast(const std_array<From, Count>& values) NOEXCEPT
2,260,373✔
84
{
85
    using to = std_array<To, proportion<Count, From, To>>;
86
    return *pointer_cast<const to>(values.data());
2,260,239✔
87
}
88

89
// Avoids cast of rvalue to reference, which would dangle.
90
template <typename To, size_t Count, typename From>
91
inline std_array<To, proportion<Count, From, To>>
92
array_cast(std_array<From, Count>&& values) NOEXCEPT
93
{
94
    return array_cast<To>(unmove(values));
95
}
96

97
// Cast array(T1) to not-greater-sized array(T2).
98
// ----------------------------------------------------------------------------
99

100
template <typename To, size_t ToCount, size_t FromOffset, typename From,
101
    size_t FromCount,
102
    if_lesser<FromOffset, FromCount>,
103
    if_portional<ToCount, To, FromCount - FromOffset, From>>
104
inline std_array<To, ToCount>&
105
array_cast(std_array<From, FromCount>& values) NOEXCEPT
2,508,353✔
106
{
107
    using to = std_array<To, ToCount>;
108
    return *pointer_cast<to>(std::next(values.data(), FromOffset));
2,508,353✔
109
}
110

111
template <typename To, size_t ToCount, size_t FromOffset, typename From,
112
    size_t FromCount,
113
    if_lesser<FromOffset, FromCount>,
114
    if_portional<ToCount, To, FromCount - FromOffset, From>>
115
inline const std_array<To, ToCount>&
116
array_cast(const std_array<From, FromCount>& values) NOEXCEPT
66✔
117
{
118
    using to = std_array<To, ToCount>;
119
    return *pointer_cast<const to>(std::next(values.data(), FromOffset));
66✔
120
}
121

122
// Avoids cast of rvalue to reference, which would dangle.
123
// Cannot offset into move assignment as the whole instance must be moved.
124
template <typename To, size_t ToCount, typename From, size_t FromCount,
125
    if_portional<ToCount, To, FromCount, From>>
126
inline std_array<To, ToCount>
127
array_cast(std_array<From, FromCount>&& values) NOEXCEPT
2,406,912✔
128
{
129
    return array_cast<To, ToCount>(unmove(values));
2,406,912✔
130
}
131

132
// Cast Integral1* to array(Integral2).
133
// ----------------------------------------------------------------------------
134

135
template <typename To, size_t Size, typename From,
136
    if_integral_integer<From>,
137
    if_integral_integer<To>>
138
inline std_array<To, Size>&
139
unsafe_array_cast(From* bytes) NOEXCEPT
140
{
141
    return *pointer_cast<std_array<To, Size>>(bytes);
142
}
143

144
template <typename To, size_t Size, typename From,
145
    if_integral_integer<From>,
146
    if_integral_integer<To>>
147
inline const std_array<To, Size>&
148
unsafe_array_cast(const From* bytes) NOEXCEPT
×
149
{
150
    return *pointer_cast<const std_array<To, Size>>(bytes);
×
151
}
152

153
// Cast Integral1* to array(array(Integral2), Size).
154
// ----------------------------------------------------------------------------
155

156
template <typename To, size_t Size, typename From,
157
    if_integral_integer<From>,
158
    if_integral_array<To>>
159
inline std_array<To, Size>&
160
unsafe_array_cast(From* bytes) NOEXCEPT
161
{
162
    return *pointer_cast<std_array<To, Size>>(bytes);
163
}
164

165
template <typename To, size_t Size, typename From,
166
    if_integral_integer<From>,
167
    if_integral_array<To>>
168
inline const std_array<To, Size>&
169
unsafe_array_cast(const From* bytes) NOEXCEPT
170
{
171
    return *pointer_cast<const std_array<To, Size>>(bytes);
172
}
173

174
// Cast Integral1* to a vector(array(Integral)&, count).
175
// ----------------------------------------------------------------------------
176

177
template <typename To, typename From,
178
    if_integral_integer<From>,
179
    if_integral_array<To>>
180
inline std_vector<std::reference_wrapper<To>>
181
unsafe_vector_cast(From* bytes, size_t count) NOEXCEPT
1✔
182
{
183
    using inner_type = array_element<To>;
184
    constexpr auto inner_count = array_count<To>;
185
    std_vector<std::reference_wrapper<To>> out{};
1✔
186
    out.reserve(count);
1✔
187

188
    for (size_t element = 0; element < count; ++element)
4✔
189
    {
190
        out.emplace_back(unsafe_array_cast<inner_type, inner_count>(bytes));
3✔
191
        std::advance(bytes, size_of<To>());
192
    }
193

194
    return out;
1✔
195
}
196

197
template <typename To, typename From,
198
    if_integral_integer<From>,
199
    if_integral_array<To>>
200
inline std_vector<std::reference_wrapper<const To>>
201
unsafe_vector_cast(const From* bytes, size_t count) NOEXCEPT
1✔
202
{
203
    using inner_type = array_element<To>;
204
    constexpr auto inner_count = array_count<To>;
205
    std_vector<std::reference_wrapper<const To>> out{};
1✔
206
    out.reserve(count);
1✔
207

208
    for (size_t element = 0; element < count; ++element)
4✔
209
    {
210
        out.emplace_back(unsafe_array_cast<inner_type, inner_count>(bytes));
3✔
211
        std::advance(bytes, size_of<To>());
212
    }
213

214
    return out;
1✔
215
}
216

217
} // namespace system
218
} // namespace libbitcoin
219

220
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc