AsmGrader 0.0.0
Loading...
Searching...
No Matches
decomposer.hpp
Go to the documentation of this file.
1
4
8
9#include <cstddef>
10#include <string_view>
11#include <tuple>
12#include <utility>
13
14namespace asmgrader {
15
22{
23};
24
27template <StaticString Op, typename... Types>
29{
30 constexpr explicit(false) DecomposedExpr(Types&&... args)
31 : operands{std::forward<Types>(args)...} {}
32
33 std::tuple<Types&&...> operands;
34
35 static constexpr std::size_t arity = sizeof...(Types);
36 static constexpr std::string_view op = Op;
37
39 template <typename U>
40 constexpr DecomposedExpr<Op, Types...>& operator=(const U& /*unused*/);
41};
42
43template <typename T>
44constexpr DecomposedExpr<"", T> operator<=(Decomposer /*tag*/, T&& expr_lhs) {
45 return {std::forward<T>(expr_lhs)};
46}
47
49
50template <typename T, typename U>
51constexpr DecomposedExpr<"==", T, U> operator==(DecomposedExpr<"", T>&& expr_lhs, U&& expr_rhs) {
52 return {std::get<0>(std::move(expr_lhs).operands), std::forward<U>(expr_rhs)};
53}
54
55template <typename T, typename U>
56constexpr DecomposedExpr<"!=", T, U> operator!=(DecomposedExpr<"", T>&& expr_lhs, U&& expr_rhs) {
57 return {std::get<0>(std::move(expr_lhs).operands), std::forward<U>(expr_rhs)};
58}
59
60template <typename T, typename U>
61constexpr DecomposedExpr<"<", T, U> operator<(DecomposedExpr<"", T>&& expr_lhs, U&& expr_rhs) {
62 return {std::get<0>(std::move(expr_lhs).operands), std::forward<U>(expr_rhs)};
63}
64
65template <typename T, typename U>
66constexpr DecomposedExpr<"<=", T, U> operator<=(DecomposedExpr<"", T>&& expr_lhs, U&& expr_rhs) {
67 return {std::get<0>(std::move(expr_lhs).operands), std::forward<U>(expr_rhs)};
68}
69
70template <typename T, typename U>
71constexpr DecomposedExpr<">", T, U> operator>(DecomposedExpr<"", T>&& expr_lhs, U&& expr_rhs) {
72 return {std::get<0>(std::move(expr_lhs).operands), std::forward<U>(expr_rhs)};
73}
74
75template <typename T, typename U>
76constexpr DecomposedExpr<">=", T, U> operator>=(DecomposedExpr<"", T>&& expr_lhs, U&& expr_rhs) {
77 return {std::get<0>(std::move(expr_lhs).operands), std::forward<U>(expr_rhs)};
78}
79
81// Includes:
82// bitwise binary ops
83// logical binary ops
84// assignment and compound assignment ops
85// comma op
86
87// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) - rational: static_assert requires a string literal pre-c++26
88#define STATIC_ASSERT_PRE \
89 "=====================================================================================================" \
90 "=========================================================== !!!!!!!!!!!!!!!!! " \
91 "Operator "
92
93// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) - rational: static_assert requires a string literal pre-c++26
94#define STATIC_ASSERT_POST \
95 " is not supported for decomposition! Wrap it in parentheses." \
96 " !!!!!!!!!!!!!!!!! " \
97 "=====================================================================================================" \
98 "=========================================================== "
99
100// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) - rational: static_assert requires a string literal pre-c++26
101#define STATIC_ASSERT_CHAINED_POST \
102 " is not supported to be chained with decomposition. Wrap it in parentheses, or fix the logic error." \
103 " !!!!!!!!!!!!!!!!! " \
104 "=====================================================================================================" \
105 "=========================================================== "
106
107template <StaticString Op, typename... Ts>
108template <typename U>
109constexpr DecomposedExpr<Op, Ts...>& DecomposedExpr<Op, Ts...>::operator=(const U& /*unused*/) {
110 static_assert(always_false_v<decltype(Op)>, STATIC_ASSERT_PRE "=" STATIC_ASSERT_POST);
111}
112
113// NOLINTBEGIN(cppcoreguidelines-rvalue-reference-param-not-moved) - unnamed parameter
114
115#define DISABLE_OPERATOR(op) \
116 template <StaticString Op, typename... Ts, typename U> \
117 constexpr void operator op(DecomposedExpr<Op, Ts...>&& /*expr_lhs*/, U&& /*expr_rhs*/) { \
118 static_assert(always_false_v<U>, STATIC_ASSERT_PRE #op STATIC_ASSERT_POST); \
119 }
120#define DISABLE_CHAINED_OPERATOR(op) \
121 template <StaticString Op, typename... Ts, typename U> \
122 constexpr void operator op(DecomposedExpr<Op, Ts...>&& /*expr_lhs*/, U&& /*expr_rhs*/) { \
123 static_assert(always_false_v<U>, STATIC_ASSERT_PRE #op STATIC_ASSERT_CHAINED_POST); \
124 }
125
141#define COMMA ,
143#undef COMMA
144
151
152#undef DISABLE_CHAINED_OPERATOR
153#undef DISABLE_OPERATOR
154#undef STATIC_ASSERT_POST
155#undef STATIC_ASSERT_PRE
156
157// NOLINTEND(cppcoreguidelines-rvalue-reference-param-not-moved)
158
159} // namespace asmgrader
A non-movable and non-copyable type.
Definition class_traits.hpp:38
A fully compile-time capable string type Guaranteed to be null-terminated.
Definition static_string.hpp:59
#define STATIC_ASSERT_POST
Definition decomposer.hpp:94
#define COMMA
Definition decomposer.hpp:141
#define DISABLE_OPERATOR(op)
Definition decomposer.hpp:115
#define STATIC_ASSERT_PRE
Definition decomposer.hpp:88
Definition asm_buffer.hpp:20
constexpr bool always_false_v
Definition always_false.hpp:16
constexpr DecomposedExpr<">=", T, U > operator>=(DecomposedExpr<"", T > &&expr_lhs, U &&expr_rhs)
Definition decomposer.hpp:76
constexpr DecomposedExpr<"==", T, U > operator==(DecomposedExpr<"", T > &&expr_lhs, U &&expr_rhs)
Definition decomposer.hpp:51
constexpr DecomposedExpr<"!=", T, U > operator!=(DecomposedExpr<"", T > &&expr_lhs, U &&expr_rhs)
Definition decomposer.hpp:56
constexpr DecomposedExpr<"", T > operator<=(Decomposer, T &&expr_lhs)
Definition decomposer.hpp:44
DISABLE_CHAINED_OPERATOR(==)
StaticString(const char(&input)[N]) -> StaticString< N - 1 >
Stores references to rhs and lhs of a comparison expression, serving as an interface to the "decompos...
Definition decomposer.hpp:29
std::tuple< Types &&... > operands
Definition decomposer.hpp:33
static constexpr std::size_t arity
Definition decomposer.hpp:35
static constexpr std::string_view op
Definition decomposer.hpp:36
constexpr DecomposedExpr< Op, Types... > & operator=(const U &)
operator= is disabled via static_assert(false, ...)
Just a tag type for operator overloading purposes Intended use is on the lhs of operator<= e....
Definition decomposer.hpp:22