AsmGrader 0.0.0
Loading...
Searching...
No Matches
byte.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <fmt/base.h>
7#include <fmt/format.h>
8#include <gsl/util>
9
10#include <concepts>
11#include <cstddef>
12#include <stdexcept>
13
14namespace asmgrader {
15
17class Byte
18{
19public:
20 constexpr Byte() = default;
21 explicit(false) constexpr Byte(u8 val)
22 : value{val} {};
23
24 explicit(false) constexpr Byte(std::byte val)
25 : Byte{static_cast<u8>(val)} {}
26
32 template <std::integral Narrowable>
33 requires(!std::same_as<Narrowable, u8>)
34 explicit(false) consteval Byte(Narrowable val)
35 : value{narrow_from(val).value} {}
36
39 template <std::integral Narrowable>
40 static constexpr Byte narrow_from(Narrowable val) {
41 constexpr auto max_val = 255;
42
43 if (val < 0 || val > max_val) {
44 throw std::out_of_range("value is not representable as a byte");
45 }
46
47 return gsl::narrow_cast<u8>(val);
48 }
49
51 explicit constexpr operator u8() const { return value; }
52
54 explicit constexpr operator std::byte() const { return std::byte{value}; }
55
57 constexpr bool operator==(const Byte& rhs) const = default;
58
60 constexpr auto operator<=>(const Byte& rhs) const = default;
61
62 // /// Equality operator with an integer type
63 // /// Defined to prevent ambiguity with implicit conversions.
64 // template <std::integral IntType>
65 // requires(!std::same_as<IntType, u8>)
66 // constexpr bool operator==(Narrowable) const {};
67 //
68 // /// Comparison operators with an integer type
69 // /// Defined to prevent ambiguity with implicit conversions.
70 // template <std::integral IntType>
71 // requires(!std::same_as<IntType, u8>)
72 // constexpr auto operator<=>(IntType) const {};
73
75 constexpr Byte operator~() const { return static_cast<u8>(~value); }
76
77// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
78#define DEF_BINARY_OP(op) \
79 constexpr Byte operator op(const Byte& rhs) const { return static_cast<u8>(value op rhs.value); }
80// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
81#define DEF_BINARY_ASSIGN_OP(op) \
82 constexpr Byte& operator op(const Byte & rhs) { \
83 value op rhs.value; \
84 return *this; \
85 }
86
97
108
109#undef DEF_BINARY_OP
110#undef DEF_BINARY_ASSIGN_OP
111
112 u8 value{};
113};
114
115static_assert(sizeof(Byte) == 1);
116
117} // namespace asmgrader
118
119template <>
121{
123 fmt::formatter<UnderlyingT> f;
124
125 bool empty_format_spec{};
126
127 constexpr auto parse(fmt::format_parse_context& ctx) {
128 ctx.advance_to(::asmgrader::DebugFormatter::parse(ctx));
129 if (ctx.begin() == ctx.end() || *ctx.begin() == '}') {
130 empty_format_spec = true;
131 }
132 return f.parse(ctx);
133 }
134
135 constexpr auto format(const ::asmgrader::Byte& from, fmt::format_context& ctx) const {
136 if (is_debug_format) {
137 ctx.advance_to(fmt::format_to(ctx.out(), "Byte{{"));
138 }
139
140 // hex formatting by default when nothing else is specified
141 if (empty_format_spec) {
142 if (is_debug_format) {
143 *ctx.out()++ = '0';
144 *ctx.out()++ = 'x';
145 }
146 ctx.advance_to(fmt::format_to(ctx.out(), "{:02X}", from.value));
147 } else {
148 ctx.advance_to(f.format(from.value, ctx));
149 }
150
151 if (is_debug_format) {
152 *ctx.out()++ = '}';
153 }
154
155 return ctx.out();
156 }
157};
#define DEF_BINARY_ASSIGN_OP(op)
Definition byte.hpp:81
#define DEF_BINARY_OP(op)
Definition byte.hpp:78
More user-friendly interface wrapper for a byte-like integral.
Definition byte.hpp:18
u8 value
Bitwise or.
Definition byte.hpp:112
static constexpr Byte narrow_from(Narrowable val)
Attempt to perform a narrowing conversion from val to a Byte.
Definition byte.hpp:40
constexpr bool operator==(const Byte &rhs) const =default
Compiler generated equality operator with another Byte
constexpr auto operator<=>(const Byte &rhs) const =default
Compiler generated comparison operators with another Byte
constexpr Byte operator~() const
Unary bitwise not.
Definition byte.hpp:75
constexpr Byte()=default
Definition asm_buffer.hpp:20
Definition debug.hpp:9
constexpr auto parse(fmt::format_parse_context &ctx)
Definition debug.hpp:12
constexpr auto parse(fmt::format_parse_context &ctx)
Definition byte.hpp:127
fmt::formatter< UnderlyingT > f
Definition byte.hpp:123
decltype(::asmgrader::Byte::value) UnderlyingT
Definition byte.hpp:122
constexpr auto format(const ::asmgrader::Byte &from, fmt::format_context &ctx) const
Definition byte.hpp:135