Use a custom generic tagged union Either instead of std::variant for efficiency (#1476)

* Implement custom generic tagged union `Either`

This should be more efficient than `std::variant`, while still
keeping runtime safety as it `assert`s when `get`ting values.

* Use `Either` for RPN expressions

* Use `Either` for file stack node data

* Use `Either` for `File` buffer

* Use `Either` for `STRFMT` args

* Use `Either` for RGBLINK symbol values

* Support an equivalent of `std::monostate` for `Either`

* Use `Either` for lexer tokens

* Use `Either` for symbol values

* Use `Either` for lexer mmap/buffer state
This commit is contained in:
Sylvie
2024-08-20 15:19:11 -04:00
committed by GitHub
parent 7d98b9a900
commit 57c3d74b9e
17 changed files with 303 additions and 174 deletions

View File

@@ -7,8 +7,8 @@
#include <stdint.h>
#include <string>
#include <variant>
#include "either.hpp"
#include "linkdefs.hpp"
struct FileStackNode;
@@ -28,14 +28,14 @@ struct Symbol {
char const *objFileName;
FileStackNode const *src;
int32_t lineNo;
std::variant<
Either<
int32_t, // Constants just have a numeric value
Label // Label values refer to an offset within a specific section
>
data;
Label &label();
Label const &label() const;
Label &label() { return data.get<Label>(); }
Label const &label() const { return data.get<Label>(); }
};
void sym_ForEach(void (*callback)(Symbol &));