AsmGrader 0.0.0
Loading...
Searching...
No Matches
byte_array.hpp
Go to the documentation of this file.
1#pragma once
2
6
7#include <gsl/assert>
8#include <libassert/assert.hpp>
9#include <range/v3/algorithm/copy.hpp>
10#include <range/v3/algorithm/transform.hpp>
11#include <range/v3/iterator/traits.hpp>
12#include <range/v3/range/access.hpp>
13#include <range/v3/range/concepts.hpp>
14#include <range/v3/range/primitives.hpp>
15#include <range/v3/range/traits.hpp>
16
17#include <array>
18#include <cstddef>
19#include <memory>
20#include <type_traits>
21#include <utility>
22
23namespace asmgrader {
24
25template <std::size_t Size, EndiannessKind Endianness>
27{
28public:
29 // A bunch of aliases for use with algorithm templates that check for them
31 using allocator_type = std::allocator<Byte>;
32 using size_type = std::size_t;
33 using difference_type = std::ptrdiff_t;
37 using const_pointer = const value_type*;
38 using iterator = std::array<Byte, Size>::iterator;
39 using const_iterator = std::array<Byte, Size>::const_iterator;
40 using reverse_iterator = std::array<Byte, Size>::reverse_iterator;
41 using const_reverse_iterator = std::array<Byte, Size>::const_reverse_iterator;
42
43 Byte& operator[](size_t idx) { return data[idx]; }
44
45 const Byte& operator[](size_t idx) const { return data[idx]; }
46
47 constexpr Byte& at(size_t idx) { return data.at(idx); }
48
49 const Byte& at(size_t idx) const { return data.at(idx); }
50
51 constexpr bool empty() const { return data.empty(); }
52
53 constexpr auto begin() { return data.begin(); }
54
55 constexpr auto begin() const { return data.begin(); }
56
57 constexpr auto cbegin() const { return data.cend(); }
58
59 constexpr auto end() { return data.end(); }
60
61 constexpr auto end() const { return data.end(); }
62
63 constexpr auto cend() const { return data.cend(); }
64
65 constexpr std::size_t size() const { return data.size(); }
66
67 std::array<Byte, Size> data;
68
69private:
70 template <ranges::range Range>
71 requires requires(ranges::range_value_t<Range> value) {
72 { Byte{value} };
73 }
74 constexpr void from_range(Range&& range) {
75 ASSERT(get_static_size_or<Range>(ranges::size(range)) <= Size);
76
77 ranges::transform(std::forward<Range>(range), data.begin(), [](Byte value) { return Byte{value}; });
78 }
79};
80
82template <typename T, typename... U>
83ByteArray(T, U...) -> ByteArray<sizeof...(U) + 1, EndiannessKind::Native>;
84
85template <std::size_t N>
87
88static_assert(std::is_aggregate_v<NativeByteArray<0>>);
89static_assert(std::is_aggregate_v<NativeByteArray<1>>);
90static_assert(std::is_aggregate_v<NativeByteArray<10>>);
91
92} // namespace asmgrader
93
94namespace std {
95
97template <std::size_t Size>
98// See: https://en.cppreference.com/w/cpp/utility/tuple_size.html
99// NOLINTNEXTLINE(cert-dcl58-cpp) - this is well defined and probably a clang-tidy bug
100struct tuple_size<::asmgrader::NativeByteArray<Size>> : public std::integral_constant<std::size_t, Size>
101{
102};
103
105template <std::size_t I, std::size_t N>
106 requires(I < N)
107// See: https://en.cppreference.com/w/cpp/container/array/tuple_element.html
108// NOLINTNEXTLINE(cert-dcl58-cpp) - this is well defined and probably a clang-tidy bug
109struct tuple_element<I, ::asmgrader::NativeByteArray<N>>
110{
112};
113
114} // namespace std
115
117template <std::size_t I, std::size_t N>
118 requires(I < N)
119constexpr ::asmgrader::Byte& get(::asmgrader::NativeByteArray<N>& arr) {
120 return arr.data.at(I);
121}
122
124template <std::size_t I, std::size_t N>
125 requires(I < N)
126constexpr const ::asmgrader::Byte& get(const ::asmgrader::NativeByteArray<N>& arr) {
127 return arr.data.at(I);
128}
129
131template <std::size_t I, std::size_t N>
132 requires(I < N)
133// TODO: double check this rvalue usage
134// NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) - I think this is correct?
135constexpr ::asmgrader::Byte&& get(::asmgrader::NativeByteArray<N>&& arr) {
136 return arr.data.at(I);
137}
138
140template <std::size_t I, std::size_t N>
141 requires(I < N)
142constexpr const ::asmgrader::Byte&& get(const ::asmgrader::NativeByteArray<N>&& arr) {
143 return arr.data.at(I);
144}
constexpr ::asmgrader::Byte & get(::asmgrader::NativeByteArray< N > &arr)
Specialization of get to play nice with algorithms that work on tuple-like types.
Definition byte_array.hpp:119
Definition byte_array.hpp:27
std::array< Byte, Size >::const_reverse_iterator const_reverse_iterator
Definition byte_array.hpp:41
std::size_t size_type
Definition byte_array.hpp:32
std::ptrdiff_t difference_type
Definition byte_array.hpp:33
std::array< Byte, Size >::const_iterator const_iterator
Definition byte_array.hpp:39
constexpr bool empty() const
Definition byte_array.hpp:51
constexpr auto cbegin() const
Definition byte_array.hpp:57
constexpr auto begin()
Definition byte_array.hpp:53
std::array< Byte, Size >::reverse_iterator reverse_iterator
Definition byte_array.hpp:40
const Byte & operator[](size_t idx) const
Definition byte_array.hpp:45
std::allocator< Byte > allocator_type
Definition byte_array.hpp:31
Byte & operator[](size_t idx)
Definition byte_array.hpp:43
std::array< Byte, Size >::iterator iterator
Definition byte_array.hpp:38
std::array< Byte, Size > data
Definition byte_array.hpp:67
constexpr auto end() const
Definition byte_array.hpp:61
constexpr std::size_t size() const
Definition byte_array.hpp:65
const Byte & at(size_t idx) const
Definition byte_array.hpp:49
constexpr Byte & at(size_t idx)
Definition byte_array.hpp:47
constexpr auto end()
Definition byte_array.hpp:59
constexpr auto cend() const
Definition byte_array.hpp:63
constexpr auto begin() const
Definition byte_array.hpp:55
More user-friendly interface wrapper for a byte-like integral.
Definition byte.hpp:18
Definition asm_buffer.hpp:20
constexpr std::size_t get_static_size_or(std::size_t default_value)
Definition static_size.hpp:29
Definition byte_array.hpp:94
#define N
Definition test_macros.hpp:147