AsmGrader 0.0.0
Loading...
Searching...
No Matches
bit_casts.hpp
Go to the documentation of this file.
1#pragma once
2
10
11#include <range/v3/algorithm/copy_n.hpp>
12#include <range/v3/algorithm/for_each.hpp>
13#include <range/v3/algorithm/reverse.hpp>
14#include <range/v3/iterator/access.hpp>
15#include <range/v3/iterator/concepts.hpp>
16#include <range/v3/iterator/traits.hpp>
17#include <range/v3/range/access.hpp>
18#include <range/v3/range/concepts.hpp>
19#include <range/v3/range/conversion.hpp>
20#include <range/v3/range/traits.hpp>
21#include <range/v3/range_fwd.hpp>
22#include <range/v3/utility/semiregular_box.hpp>
23#include <range/v3/view/adaptor.hpp>
24#include <range/v3/view/all.hpp>
25#include <range/v3/view/concat.hpp>
26#include <range/v3/view/facade.hpp>
27#include <range/v3/view/for_each.hpp>
28#include <range/v3/view/join.hpp>
29#include <range/v3/view/single.hpp>
30#include <range/v3/view/transform.hpp>
31#include <range/v3/view/view.hpp>
32
33#include <array>
34#include <concepts>
35#include <cstddef>
36#include <type_traits>
37
38namespace asmgrader {
39
40namespace detail {
41
42template <EndiannessKind To, ranges::range Range>
43constexpr void maybe_reverse_endianness(Range& range) {
44 if constexpr (To != EndiannessKind::Native) {
45 ranges::reverse(range);
46 }
47}
48
49template <template <std::size_t, EndiannessKind> typename SizedTo, std::size_t Size>
51{
52 template <EndiannessKind Endianness>
53 using templated = SizedTo<Size, Endianness>;
54};
55
56} // namespace detail
57
70template <template <EndiannessKind> typename To, EndiannessKind Endianness, ranges::range Range>
71 requires(std::is_trivially_copyable_v<ranges::range_value_t<Range>>)
72constexpr auto to_bytes(const Range& range) {
73 To<Endianness> buffer{};
74
75 if constexpr (requires(To<Endianness> rng, std::size_t new_size) { rng.resize(new_size); }) {
76 auto size = sizeof(ranges::range_value_t<Range>) * range.size();
77 buffer.resize(size);
78 }
79
80 auto copy_next = [buf_iter = ranges::begin(buffer)](const auto& val) mutable {
81 auto byte_array = std::bit_cast<std::array<Byte, sizeof(val)>>(val);
83 ranges::copy_n(byte_array.begin(), byte_array.size(), buf_iter);
84 buf_iter += byte_array.size();
85 };
86
87 ranges::for_each(range, copy_next);
88
89 return buffer;
90}
91
96template <std::same_as<NativeByteVector> NativeTo, ranges::range Range>
97 requires(std::is_trivially_copyable_v<ranges::range_value_t<Range>>)
98constexpr auto to_bytes(const Range& range) {
100}
101
107template <template <std::size_t, EndiannessKind> typename SizedTo, std::size_t Size, EndiannessKind Endianness,
108 ranges::range Range>
109 requires(std::is_trivially_copyable_v<ranges::range_value_t<Range>>)
110constexpr auto to_bytes(const Range& range) {
111 return to_bytes<detail::partial_bytearray_spec<SizedTo, Size>::template templated, Endianness>(range);
112}
113
117template <template <std::size_t, EndiannessKind> typename SizedTo, EndiannessKind Endianness, ranges::range Range>
118 requires(std::is_trivially_copyable_v<ranges::range_value_t<Range>> &&
119 std::is_trivially_copyable_v<ranges::range_value_t<Range>>)
120constexpr auto to_bytes(const Range& range) {
121 static_assert(HasStaticSize<Range>, "Range must have a statically accessible size in order"
122 " to infer size of ByteArray");
123
124 constexpr auto size = sizeof(ranges::range_value_t<Range>) * get_static_size<Range>();
125
127}
128
133template <template <std::size_t> typename NativeSizedTo, std::size_t Size, ranges::range Range>
134 requires(std::same_as<NativeSizedTo<Size>, NativeByteArray<Size>> &&
135 std::is_trivially_copyable_v<ranges::range_value_t<Range>>)
136constexpr auto to_bytes(const Range& range) {
138}
139
143template <template <std::size_t> typename NativeSizedTo, ranges::range Range>
144 requires(std::same_as<NativeSizedTo<0>, NativeByteArray<0>> &&
145 std::is_trivially_copyable_v<ranges::range_value_t<Range>>)
146constexpr auto to_bytes(const Range& range) {
147 static_assert(HasStaticSize<Range>, "Range must have a statically accessible size in order"
148 " to infer size of NativeByteArray");
149
151}
152
160template <template <EndiannessKind> typename To, EndiannessKind Endianness, C<std::is_trivially_copyable>... Ts>
161constexpr auto to_bytes(const Ts&... values) {
162 To<Endianness> buffer{};
163
164 if constexpr (requires(To<Endianness> rng, std::size_t new_size) { rng.resize(new_size); }) {
165 constexpr auto size = (sizeof(Ts) + ...);
166 buffer.resize(size);
167 }
168
169 auto copy_next = [buf_iter = ranges::begin(buffer)](const auto& val) mutable {
170 auto byte_array = std::bit_cast<std::array<Byte, sizeof(val)>>(val);
172 ranges::copy_n(byte_array.begin(), byte_array.size(), buf_iter);
173 buf_iter += byte_array.size();
174 };
175
176 (copy_next(values), ...);
177
178 return buffer;
179}
180
184template <std::same_as<NativeByteVector> NativeTo, C<std::is_trivially_copyable>... Ts>
185constexpr auto to_bytes(const Ts&... values) {
187}
188
192template <template <std::size_t, EndiannessKind> typename SizedTo, std::size_t Size, EndiannessKind Endianness,
194constexpr auto to_bytes(const Ts&... values) {
195 return to_bytes<detail::partial_bytearray_spec<SizedTo, Size>::template templated, Endianness>(values...);
196}
197
201template <template <std::size_t, EndiannessKind> typename SizedTo, EndiannessKind Endianness,
203constexpr auto to_bytes(const Ts&... values) {
204 constexpr auto size = (0 + ... + sizeof(Ts));
205
206 return to_bytes<SizedTo, size, Endianness>(values...);
207}
208
212template <template <std::size_t> typename NativeSizedTo, std::size_t Size, C<std::is_trivially_copyable>... Ts>
213 requires(std::same_as<NativeSizedTo<Size>, NativeByteArray<Size>>)
214constexpr auto to_bytes(const Ts&... values) {
216}
217
221template <template <std::size_t N> typename NativeSizedTo, C<std::is_trivially_copyable>... Ts>
222 requires(std::same_as<NativeSizedTo<0>, NativeByteArray<0>>)
223constexpr auto to_bytes(const Ts&... values) {
225}
226
232template <EndiannessKind Endianness = EndiannessKind::Native>
233constexpr decltype(auto) as_bytes() {
234 return ranges::views::for_each([](const auto& val) { return to_bytes<ByteArray, Endianness>(val); });
235}
236
237} // namespace asmgrader
More user-friendly interface wrapper for a byte-like integral.
Definition byte.hpp:18
Definition static_size.hpp:13
constexpr void maybe_reverse_endianness(Range &range)
Definition bit_casts.hpp:43
Definition asm_buffer.hpp:20
consteval std::size_t get_static_size()
Definition static_size.hpp:19
EndiannessKind
Definition os.hpp:47
constexpr auto to_bytes(const Range &range)
Reinterpret a range of trivially copyable values as a ByteVector of specified endianness,...
Definition bit_casts.hpp:72
constexpr decltype(auto) as_bytes()
callable providing a view adaptor to reinterpret a range of trivially copyable values as bytes.
Definition bit_casts.hpp:233
ByteArray< N, EndiannessKind::Native > NativeByteArray
Definition byte_array.hpp:86
SizedTo< Size, Endianness > templated
Definition bit_casts.hpp:53
#define C
Definition test_macros.hpp:149