AsmGrader 0.0.0
Loading...
Searching...
No Matches
stringize.hpp
Go to the documentation of this file.
1
3#pragma once
4
10
11#include <boost/type_index.hpp>
12#include <fmt/base.h>
13#include <fmt/format.h>
14#include <range/v3/range/concepts.hpp>
15#include <range/v3/view/transform.hpp>
16
17#include <concepts>
18#include <span>
19#include <string>
20#include <string_view>
21#include <utility>
22
36
39{
40 std::string resolve_blocks(bool do_colorize) const;
41 std::string syntax_highlight() const;
42
43 std::string original;
44};
45
46namespace detail {
47
48// these are defined up here to allow for nested calls in str_default
49
50struct ReprFn
51{
52 template <typename T>
53 StringizeResult operator()(std::span<const inspection::Token> tokens, std::string_view raw_str, const T& val) const;
54
55 template <typename T>
56 constexpr fmt::formattable auto pre(std::span<const inspection::Token> tokens, std::string_view raw_str,
57 const T& val) const;
58};
59
61
63struct StrFn
64{
65 template <typename T>
66 StringizeResult operator()(const T& val) const;
67
68 template <typename T>
69 constexpr fmt::formattable auto pre(const T& val) const;
70};
71
73
74inline std::string str_default(const std::convertible_to<std::string_view> auto& val) {
75 return fmt::format("{:?}", std::string_view{val});
76}
77
78// TODO: base output shennanigans
79inline std::string str_default(std::integral auto val) {
80 return fmt::format("{}", val);
81}
82
83inline std::string str_default(char val) {
84 return fmt::format("{:?}", val);
85}
86
87// TODO: binary / hex output shennanigans
88inline std::string str_default(std::floating_point auto val) {
89 return fmt::format("{}", val);
90}
91
92template <ranges::range Range>
93 requires(!std::convertible_to<Range, std::string_view>) // prevent ambiguity with other overload
94inline std::string str_default(const Range& val) {
95 return fmt::to_string(fmt::join(
96 val | ranges::views::transform([](const auto& elem) { return str_fn_dispatcher(elem).original; }), ", "));
97}
98
99template <typename T, typename E>
100inline std::string str_default(const Expected<T, E>& expected) {
101 // TODO: some kind of (globally?) configurable color scheme, use an "error color" here
102 if (expected.has_value()) {
103 if constexpr (std::same_as<T, void>) {
104 return "void";
105 } else {
106 // FIXME: ??
107 // hmm... Still not a template expert. I hope this doesn't instantiate and resolve overloads here.
108 return str_fn_dispatcher(expected.value()).original;
109 }
110 }
111 std::string err_str = [&expected]() -> std::string {
112 if constexpr (std::same_as<E, void>) {
113 return "void";
114 } else {
115 // don't want to nest within the error coloring block below, since that's still not supported
116 return str_fn_dispatcher(expected.error()).resolve_blocks(/*do_colorize=*/false);
117 }
118 }();
119 return fmt::format("%#`<fg:red>{}`", err_str);
120}
121
122inline std::string str_default(ErrorKind error_kind) {
123 return fmt::format("{}", error_kind);
124}
125
126template <typename T>
127StringizeResult ReprFn::operator()(std::span<const inspection::Token> tokens, std::string_view raw_str,
128 const T& val) const {
129 return {fmt::to_string(pre(tokens, raw_str, val))};
130}
131
132template <typename T>
133constexpr fmt::formattable auto ReprFn::pre(std::span<const inspection::Token> tokens, std::string_view raw_str,
134 const T& val) const {
135 if constexpr (requires { val.repr(tokens, raw_str); }) {
136 return val.repr(tokens, raw_str); // member function
137 } else if constexpr (requires { repr(tokens, raw_str, val); }) {
138 return repr(tokens, raw_str, val); // free function found via ADL
139 } else if constexpr (requires { repr_default(tokens, raw_str, val); }) {
140 return repr_default(tokens, raw_str, val); // default defined BEFORE this struct
141 } else {
142 return raw_str; // fallback
143 }
144}
145
147template <typename T>
149 return {fmt::to_string(pre(val))};
150}
151
152template <typename T>
153constexpr fmt::formattable auto StrFn::pre(const T& val) const {
154 if constexpr (requires { val.str(); }) {
155 return val.str(); // member function
156 } else if constexpr (requires { str(val); }) {
157 return str(val); // free function found via ADL
158 } else if constexpr (requires { str_default(val); }) {
159 return str_default(val); // default defined BEFORE this struct
160 } else {
161 LOG_WARN("No `str` implementation for type <{}>", boost::typeindex::type_id<T>().pretty_name());
162 return "%#`...`"; // fallback
163 }
164}
165
166} // namespace detail
167
178inline constexpr const auto& repr = detail::repr_fn_dispatcher;
179
190inline constexpr const auto& str = detail::str_fn_dispatcher;
191
192} // namespace asmgrader::stringize
std::variant wrapper for a partial implementation of C++23's expected type
Definition expected.hpp:34
constexpr U & value()
Definition expected.hpp:78
constexpr E error() const
Definition expected.hpp:149
constexpr bool has_value() const
Definition expected.hpp:64
#define LOG_WARN(...)
Definition logging.hpp:43
constexpr StrFn str_fn_dispatcher
Definition stringize.hpp:72
constexpr ReprFn repr_fn_dispatcher
Definition stringize.hpp:60
std::string str_default(const std::convertible_to< std::string_view > auto &val)
Definition stringize.hpp:74
For everything related to test requirement stringification.
Definition stringize.hpp:35
constexpr const auto & str
str customization point object The return value of this function is guaranteed to be parsable by high...
Definition stringize.hpp:190
constexpr const auto & repr
repr customization point object The return value of this function is guaranteed to be parsable by hig...
Definition stringize.hpp:178
ErrorKind
Definition error_types.hpp:11
Result type of a call to str or repr
Definition stringize.hpp:39
std::string original
Definition stringize.hpp:43
std::string syntax_highlight() const
Definition stringize.cpp:13
std::string resolve_blocks(bool do_colorize) const
Definition stringize.cpp:9
Definition stringize.hpp:51
constexpr fmt::formattable auto pre(std::span< const inspection::Token > tokens, std::string_view raw_str, const T &val) const
Definition stringize.hpp:133
StringizeResult operator()(std::span< const inspection::Token > tokens, std::string_view raw_str, const T &val) const
Definition stringize.hpp:127
str function dispatcher
Definition stringize.hpp:64
constexpr fmt::formattable auto pre(const T &val) const
Definition stringize.hpp:153
StringizeResult operator()(const T &val) const
str function dispatcher
Definition stringize.hpp:148