StormByte 2.0.0
C++26 foundation of the StormByte suite
 
Loading...
Searching...
No Matches
binary_data.hxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024-2026 David C. Manuelda (StormBytePP)
3 *
4 * This file is part of StormByte.
5 *
6 * StormByte original source is dual-licensed:
7 *
8 * 1. GNU Lesser General Public License v3.0 (or later)
9 * You may redistribute and/or modify this file under the terms of the
10 * GNU Lesser General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option)
12 * any later version.
13 *
14 * 2. Commercial license
15 * Alternatively, this file may be used under the terms of a commercial
16 * license agreement with the copyright holder
17 * (David C. Manuelda <StormByte@gmail.com>).
18 *
19 * Both licenses apply only to original StormByte source in this repository.
20 * They do not cover other StormByte modules or any third-party material
21 * shipped with this repository (including everything under thirdparty/),
22 * which remains under its own license.
23 *
24 * Neither license grants any patent rights. Any patent licenses required
25 * to use this software or third-party components must be obtained separately
26 * from the patent holders.
27 *
28 * StormByte is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU Lesser General Public License for more details.
32 *
33 * You should have received a copy of the GNU Lesser General Public License
34 * version 3 along with StormByte. If not, see
35 * <https://www.gnu.org/licenses/lgpl-3.0.html>.
36 *
37 * SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-StormByte-Commercial
38 */
39
40#pragma once
41
43#include <StormByte/cstring.hxx>
45#include <StormByte/size.hxx>
48
49#include <compare>
50#include <cstddef>
51#include <initializer_list>
52#include <iterator>
53#include <memory>
54#include <span>
55#include <string_view>
56#include <utility>
57#include <vector>
58
68namespace StormByte {
107 public:
111 using value_type = std::byte;
112
116 using size_type = std::size_t;
117
121 using difference_type = std::ptrdiff_t;
122
126 using reference = std::byte&;
127
131 using const_reference = const std::byte&;
132
136 using pointer = std::byte*;
137
141 using const_pointer = const std::byte*;
142
146 using iterator = std::byte*;
147
151 using const_iterator = const std::byte*;
152
156 using reverse_iterator = std::reverse_iterator<iterator>;
157
161 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
162
167
174
180
185 explicit BinaryData(std::span<const std::byte> bytes);
186
193
199
204 explicit BinaryData(std::string_view sv);
205
211
217 explicit BinaryData(const std::vector<std::byte>& bytes);
218
225 explicit BinaryData(std::vector<std::byte>&& bytes);
226
232 template<Type::ByteInputRange R>
234
243 template<Type::ByteInputRange R>
245
251
257
262
269
276
283
290
297
304
310 bool operator==(std::span<const std::byte> bytes) const noexcept;
311
317 bool operator!=(std::span<const std::byte> bytes) const noexcept;
318
325
331
337
343
349
355
361
367
373
379
385
391
397
403
409
415
420 bool empty() const noexcept;
421
427
433
439 void resize(const StormByte::ByteSize& new_size, std::byte value);
440
444 void shrink_to_fit();
445
449 void clear() noexcept;
450
457
464
471 std::byte& at(const StormByte::ByteSize& index);
472
479 const std::byte& at(const StormByte::ByteSize& index) const;
480
485 std::byte& front();
486
491 const std::byte& front() const;
492
497 std::byte& back();
498
503 const std::byte& back() const;
504
509 std::byte* data() noexcept;
510
515 const std::byte* data() const noexcept;
516
521 std::span<std::byte> span() noexcept;
522
527 std::span<const std::byte> span() const noexcept;
528
533 operator std::span<std::byte>() noexcept;
534
540
548 const std::span<const std::byte> bytes = span();
549 return std::vector<std::byte>(bytes.begin(), bytes.end());
550 }
551
559 STORMBYTE_FORCE_INLINE explicit operator std::vector<std::byte>() && {
560 const std::span<const std::byte> bytes = span();
561 std::vector<std::byte> out(bytes.begin(), bytes.end());
562 clear();
563 shrink_to_fit();
564 return out;
565 }
566
572 void assign(const StormByte::ByteSize& count, std::byte value);
573
578 void assign(std::span<const std::byte> bytes);
579
584 void assign(std::initializer_list<std::byte> list);
585
592 template<typename InputIt>
593 void assign(InputIt first, InputIt last);
594
599 void append(std::span<const std::byte> bytes);
600
606 void append(const std::byte* bytes, const StormByte::ByteSize& count);
607
612 void append(const BinaryData& other);
613
620
626 BinaryData& operator+=(std::span<const std::byte> bytes);
627
634
641
646 void push_back(std::byte value);
647
654 template<typename T>
655 reference emplace_back(T&& value);
656
660 void pop_back();
661
669
678
685 iterator insert(const_iterator pos, std::initializer_list<std::byte> list);
686
693 iterator insert(const_iterator pos, std::span<const std::byte> bytes);
694
703 template<typename InputIt>
705
712
720
725 void swap(BinaryData& other) noexcept;
726
735
749
750 private:
755 struct Storage;
761 std::unique_ptr<Storage> m_storage;
762 };
763
769 STORMBYTE_PUBLIC void swap(BinaryData& lhs, BinaryData& rhs) noexcept;
770
777 inline bool operator==(std::span<const std::byte> bytes, const BinaryData& data) noexcept {
778 return data == bytes;
779 }
780
787 inline bool operator!=(std::span<const std::byte> bytes, const BinaryData& data) noexcept {
788 return data != bytes;
789 }
790
797 inline std::strong_ordering operator<=>(std::span<const std::byte> bytes, const BinaryData& data) noexcept {
798 return 0 <=> (data <=> bytes);
799 }
800
801 // Out-of-line template members. Documentation lives on the declarations.
802 template<Type::ByteInputRange R>
804 : BinaryData() {
805 if constexpr (requires { std::size(range); })
806 reserve(StormByte::ByteSize{std::size(range)});
807 for (auto&& b : range)
808 push_back(static_cast<std::byte>(b));
809 }
810
811 template<Type::ByteInputRange R>
813 : BinaryData() {
814 using U = std::remove_cvref_t<R>;
816 *this = std::move(range);
817 } else {
818 if constexpr (requires { std::size(range); })
819 reserve(StormByte::ByteSize{std::size(range)});
820 for (auto&& b : range)
821 push_back(static_cast<std::byte>(b));
822 }
823 }
824
825 template<typename InputIt>
827 clear();
828 for (; first != last; ++first)
829 push_back(static_cast<std::byte>(*first));
830 }
831
832 template<typename InputIt>
834 const auto start = static_cast<std::size_t>(pos - cbegin());
835 std::size_t n = start;
836 for (; first != last; ++first) {
837 insert(cbegin() + static_cast<difference_type>(n), static_cast<std::byte>(*first));
838 ++n;
839 }
840 return begin() + static_cast<difference_type>(start);
841 }
842
843 template<typename T>
845 push_back(std::byte{ static_cast<unsigned char>(std::forward<T>(value)) });
846 return back();
847 }
848}
IEC octet length (uint64_t), implicit only to std::size_t.
DLL-boundary-safe owned contiguous sequence of std::byte.
Definition binary_data.hxx:106
iterator insert(const_iterator pos, const StormByte::ByteSize &count, std::byte value)
Insert count copies of value before pos.
BinaryData & operator+=(const BinaryData &other)
Append a copy of other.
void clear() noexcept
Drop every byte.
std::ptrdiff_t difference_type
Iterator difference.
Definition binary_data.hxx:121
void append(BinaryData &&other)
Append other, then empty it.
BinaryData & operator+=(BinaryData &&other)
Append other, then empty it.
const std::byte * const_pointer
Const pointer and iterator.
Definition binary_data.hxx:141
reference emplace_back(T &&value)
Append a byte constructed in place.
Definition binary_data.hxx:844
std::byte & reference
Mutable reference to an element.
Definition binary_data.hxx:126
CString HexDump() const
Hexadecimal dump of the occupied bytes, sixteen bytes per row.
iterator erase(const_iterator first, const_iterator last)
Erase [first, last).
std::byte * iterator
Contiguous mutable iterator.
Definition binary_data.hxx:146
const std::byte * const_iterator
Contiguous const iterator.
Definition binary_data.hxx:151
void append(std::span< const std::byte > bytes)
Append a copy of bytes.
void append(const BinaryData &other)
Append a copy of other.
void assign(const StormByte::ByteSize &count, std::byte value)
Replace contents with count copies of value.
std::byte * pointer
Mutable pointer and iterator.
Definition binary_data.hxx:136
CString HexDump(Size columns) const
Hexadecimal dump of the occupied bytes.
void swap(BinaryData &other) noexcept
Exchange storage with other.
std::size_t size_type
STL size typedef; size() returns StormByte::ByteSize.
Definition binary_data.hxx:116
void append(const std::byte *bytes, const StormByte::ByteSize &count)
Append count bytes starting at bytes.
BinaryData & operator+=(std::span< const std::byte > bytes)
Append a copy of bytes.
void reserve(const StormByte::ByteSize &new_cap)
Request capacity of at least new_cap bytes.
iterator erase(const_iterator pos)
Erase the byte at pos.
void assign(std::initializer_list< std::byte > list)
Replace contents with an initializer list.
iterator insert(const_iterator pos, std::span< const std::byte > bytes)
Insert a span before pos.
std::byte value_type
Element type.
Definition binary_data.hxx:111
iterator begin() noexcept
Mutable iterator to the first byte.
std::byte & back()
Last byte.
BinaryData() noexcept
Construct an empty sequence.
iterator insert(const_iterator pos, std::byte value)
Insert one byte before pos.
std::reverse_iterator< const_iterator > const_reverse_iterator
Const reverse iterator.
Definition binary_data.hxx:161
std::reverse_iterator< iterator > reverse_iterator
Reverse iterator.
Definition binary_data.hxx:156
void push_back(std::byte value)
Append one byte.
iterator insert(const_iterator pos, std::initializer_list< std::byte > list)
Insert an initializer list before pos.
void assign(std::span< const std::byte > bytes)
Replace contents with a copy of bytes.
const_iterator cbegin() const noexcept
Const iterator to the first byte.
void pop_back()
Remove the last byte.
const std::byte & const_reference
Const reference to an element.
Definition binary_data.hxx:131
Count of octets (uint64_t storage).
Definition byte_size.hxx:103
Owned NUL-terminated buffer, safe to use across a DLL boundary.
Definition cstring.hxx:97
Count of abstract units (uint64_t storage).
Definition size.hxx:100
Lvalue reference type (std::is_lvalue_reference).
Definition categories.hxx:97
Same type after stripping cv and references from both sides.
Definition relations.hxx:94
Root namespace of the StormByte suite.
void swap(BinaryData &lhs, BinaryData &rhs) noexcept
Exchange two sequences.
bool operator==(std::span< const std::byte > bytes, const BinaryData &data) noexcept
Equality of a span against a sequence.
Definition binary_data.hxx:777
std::strong_ordering operator<=>(std::span< const std::byte > bytes, const BinaryData &data) noexcept
Three-way comparison of a span against a sequence.
Definition binary_data.hxx:797
bool operator!=(std::span< const std::byte > bytes, const BinaryData &data) noexcept
Inequality of a span against a sequence.
Definition binary_data.hxx:787
Octet count. Defined in byte_size.hxx. Forwarded so Type::Numeral can name it.
STL namespace.
#define STORMBYTE_FORCE_INLINE
Definition platform.h:89
Host-width-stable count (uint64_t), implicit only to std::size_t.
#define STORMBYTE_PUBLIC
Definition visibility.h:52