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

libbitcoin / libbitcoin-system / 5894307386

17 Aug 2023 06:00PM UTC coverage: 80.943% (-1.9%) from 82.857%
5894307386

push

github

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

Update copyright date range, regenerate artifacts.

9752 of 12048 relevant lines covered (80.94%)

4744998.68 hits per line

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

88.31
/include/bitcoin/system/data/iterable.hpp
1
/**
2
 * Copyright (c) 2011-2023 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_ITERABLE_HPP
20
#define LIBBITCOIN_SYSTEM_DATA_ITERABLE_HPP
21

22
#include <iterator>
23
#include <bitcoin/system/data/array_cast.hpp>
24
#include <bitcoin/system/data/data_chunk.hpp>
25
#include <bitcoin/system/data/exclusive_slice.hpp>
26
#include <bitcoin/system/define.hpp>
27
#include <bitcoin/system/math/math.hpp>
28

29
namespace libbitcoin {
30
namespace system {
31

32
////template <size_t Lanes, typename Iterable,
33
////    if_std_array<typename Iterable::value_t> = true>
34
////inline std_array<typename Iterable::value_t, Lanes>&
35
////array_cast(Iterable& it) NOEXCEPT
36
////{
37
////    return unsafe_array_cast<typename Iterable::value_t, Lanes>(it.data());
38
////}
39
////
40
////template <size_t Lanes, typename Iterable,
41
////    if_std_array<typename Iterable::value_t> = true>
42
////inline const std_array<typename Iterable::value_t, Lanes>&
43
////array_cast(const Iterable& it) NOEXCEPT
44
////{
45
////    return unsafe_array_cast<typename Iterable::value_t, Lanes>(it.data());
46
////}
47
////
48
////template <size_t Lanes, typename Iterable,
49
////    if_std_array<typename Iterable::value_t> = true>
50
////inline std_array<typename Iterable::value_t, Lanes>&
51
////array_cast(Iterable& it, size_t offset) NOEXCEPT
52
////{
53
////    using block = typename Iterable::value_t;
54
////    constexpr auto size = size_of<block>();
55
////    return unsafe_array_cast<block, Lanes>(std::next(it.data(), offset * size));
56
////}
57
////
58
////template <size_t Lanes, typename Iterable,
59
////    if_std_array<typename Iterable::value_t> = true>
60
////inline const std_array<typename Iterable::value_t, Lanes>&
61
////array_cast(const Iterable& it, size_t offset) NOEXCEPT
62
////{
63
////    using block = typename Iterable::value_t;
64
////    constexpr auto size = size_of<block>();
65
////    return unsafe_array_cast<block, Lanes>(std::next(it.data(), offset * size));
66
////}
67

68
/// Iterate any data souce as a set of const std::array&.
69
template<typename Array, if_std_array<Array> = true>
70
class iterable
71
{
72
public:
73
    class iterator
74
    {
75
    public:
76
        using iterator_category = std::forward_iterator_tag;
77
        using value_type = Array;
78
        using difference_type = ptrdiff_t;
79
        using pointer = value_type const*;
80
        using reference = value_type const&;
81

82
        inline iterator(uint8_t const* position) NOEXCEPT
1,467✔
83
          : position_(position)
1,467✔
84
        {
85
        }
86

87
        inline reference operator*() const NOEXCEPT
25,040✔
88
        {
89
            using element = array_element<value_type>;
90
            constexpr auto count = array_count<value_type>;
91
            return unsafe_array_cast<element, count>(position_);
25,014✔
92
        }
93

94
        inline iterator& operator++() NOEXCEPT
149,996✔
95
        {
96
            constexpr auto size = size_of<value_type>();
97
            std::advance(position_, size);
1,602✔
98
            return *this;
149,985✔
99
        }
100

101
        inline iterator operator++(int) NOEXCEPT
4✔
102
        {
103
            auto self = *this;
4✔
104
            ++(*this);
105
            return self;
4✔
106
        }
107

108
        inline bool operator==(const iterator& other) const NOEXCEPT
150,792✔
109
        {
110
            return position_ == other.position_;
150,780✔
111
        }
112

113
        inline bool operator!=(const iterator& other) const NOEXCEPT
127,286✔
114
        {
115
            return !(*this == other);
25,759✔
116
        }
117

118
    private:
119
        uint8_t const* position_;
120
    };
121

122
public:
123
    using value_t = Array;
124
    static constexpr auto value_size = size_of<Array>();
125

126
    inline iterable() NOEXCEPT
1✔
127
      : count_(zero), begin_(nullptr), end_(nullptr)
1✔
128
    {
129
    }
130

131
    template <size_t Size>
132
    inline iterable(const data_array<Size>& data) NOEXCEPT
25✔
133
      : count_(count(Size)),
25✔
134
        begin_(data.data()),
25✔
135
        end_(std::next(begin_, count_ * value_size))
25✔
136
    {
137
    }
25✔
138

139
    inline iterable(size_t size, uint8_t const* data) NOEXCEPT
738✔
140
      : count_(count(size)),
738✔
141
        begin_(data),
738✔
142
        end_(std::next(begin_, count_ * value_size))
1,476✔
143
    {
144
    }
738✔
145

146
    inline iterable(const data_chunk& data) NOEXCEPT
147
      : count_(count(data.size())),
148
        begin_(data.data()),
149
        end_(std::next(begin_, count_ * value_size))
150
    {
151
    }
152

153
    inline iterator begin() const NOEXCEPT
742✔
154
    {
155
        return iterator(begin_);
728✔
156
    }
157

158
    inline const iterator end() const NOEXCEPT
740✔
159
    {
160
        return iterator(end_);
728✔
161
    }
162

163
    inline size_t size() const NOEXCEPT
9,744✔
164
    {
165
        return count_;
2,896✔
166
    }
167

168
    inline bool empty() const NOEXCEPT
169
    {
170
        return is_zero(size());
171
    }
172

173
    inline uint8_t const* data() const NOEXCEPT
1✔
174
    {
175
        return begin_;
1✔
176
    }
177

178
    template <size_t Elements>
179
    inline iterable& advance() NOEXCEPT
8,967✔
180
    {
181
        // This is safe for overflow, will advance to end.
182
        const auto size = std::min(Elements, count_);
8,967✔
183
        count_ -= size;
8,967✔
184
        std::advance(begin_, size * value_size);
8,967✔
185
        return *this;
8,967✔
186
    }
187

188
    template <size_t Elements>
189
    inline const std_array<value_t, Elements>& to_array() const NOEXCEPT
8,967✔
190
    {
191
        return unsafe_array_cast<value_t, Elements>(begin_);
8,967✔
192
    }
193

194
private:
195
    static constexpr size_t count(size_t size) NOEXCEPT
738✔
196
    {
197
        if constexpr (is_zero(value_size))
198
        {
199
            return zero;
200
        }
201
        else
202
        {
203
            return size / value_size;
738✔
204
        }
205
    }
206

207
    size_t count_;
208
    uint8_t const* begin_;
209
    uint8_t const* end_;
210
};
211

212
/// Iterate any non-const data souce as a non-const set of std::array&.
213
template<typename Array, if_std_array<Array> = true>
214
class mutable_iterable
215
{
216
public:
217
    class iterator
218
    {
219
    public:
220
        // std::iterator_traits
221
        using iterator_category = std::forward_iterator_tag;
222
        using value_type = Array;
223
        using difference_type = ptrdiff_t;
224
        using pointer = value_type*;
225
        using reference = value_type&;
226

227
        inline iterator(uint8_t* position) NOEXCEPT
4✔
228
          : position_(position)
4✔
229
        {
230
        }
231

232
        inline reference operator*() NOEXCEPT
233
        {
234
            using element = array_element<value_type>;
235
            constexpr auto count = array_count<value_type>;
236
            return unsafe_array_cast<element, count>(position_);
237
        }
238

239
        inline iterator& operator++() NOEXCEPT
17✔
240
        {
241
            constexpr auto size = size_of<value_type>();
242
            std::advance(position_, size);
243
            return *this;
7✔
244
        }
245

246
        inline iterator operator++(int) NOEXCEPT
247
        {
248
            auto self = *this;
249
            ++(*this);
250
            return self;
251
        }
252

253
        inline bool operator==(const iterator& other) const NOEXCEPT
21✔
254
        {
255
            return position_ == other.position_;
21✔
256
        }
257

258
        inline bool operator!=(const iterator& other) const NOEXCEPT
21✔
259
        {
260
            return !(*this == other);
261
        }
262

263
    private:
264
        uint8_t* position_;
265
    };
266

267
public:
268
    using value_t = Array;
269
    static constexpr auto value_size = size_of<Array>();
270

271
    inline mutable_iterable() NOEXCEPT
1✔
272
      : count_(zero), begin_(nullptr), end_(nullptr)
1✔
273
    {
274
    }
275

276
    template <size_t Size>
277
    inline mutable_iterable(data_array<Size>& data) NOEXCEPT
24✔
278
      : count_(count(Size)),
24✔
279
        begin_(data.data()),        
24✔
280
        end_(std::next(begin_, count_ * value_size))
24✔
281
    {
282
    }
24✔
283

284
    inline mutable_iterable(size_t size, uint8_t* data) NOEXCEPT
×
285
      : count_(count(size)),
×
286
        begin_(data),        
×
287
        end_(std::next(begin_, count_ * value_size))
×
288
    {
289
    }
×
290

291
    inline mutable_iterable(data_chunk& data) NOEXCEPT
292
      : count_(count(data.size())),
293
        begin_(data.data()),
294
        end_(std::next(begin_, count_ * value_size))
295
    {
296
    }
297

298
    inline iterator begin() NOEXCEPT
4✔
299
    {
300
        return iterator(begin_);
1✔
301
    }
302

303
    inline const iterator end() NOEXCEPT
4✔
304
    {
305
        return iterator(end_);
4✔
306
    }
307

308
    inline size_t size() const NOEXCEPT
22✔
309
    {
310
        return count_;
22✔
311
    }
312

313
    inline bool empty() const NOEXCEPT
314
    {
315
        return is_zero(size());
316
    }
317

318
    inline uint8_t* data() NOEXCEPT
319
    {
320
        return begin_;
321
    }
322

323
    template <size_t Elements>
324
    inline mutable_iterable& advance() NOEXCEPT
1✔
325
    {
326
        // This is safe for overflow, will advance to end.
327
        const auto size = std::min(Elements, count_);
1✔
328
        count_ -= size;
1✔
329
        std::advance(begin_, size * value_size);
1✔
330
        return *this;
1✔
331
    }
332

333
    template <size_t Elements>
334
    inline std_array<value_t, Elements>& to_array() NOEXCEPT
×
335
    {
336
        return unsafe_array_cast<value_t, Elements>(begin_);
×
337
    }
338

339
private:
340
    static constexpr size_t count(size_t size) NOEXCEPT
×
341
    {
342
        if constexpr (is_zero(value_size))
343
        {
344
            return zero;
345
        }
346
        else
347
        {
348
            return size / value_size;
×
349
        }
350
    }
351

352
    size_t count_;
353
    uint8_t* begin_;
354
    uint8_t* end_;
355
};
356

357
} // namespace system
358
} // namespace libbitcoin
359

360
#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