Use std::get_if instead of std::visit (#1367)

`std::visit` is (arguably) cleaner code, but older versions of gcc
and clang (not very old; the ones packaged with Ubuntu 22.04 LTS)
compile them as tables of function pointers, instead of efficient
jump tables.
This commit is contained in:
Sylvie
2024-03-20 22:37:54 -04:00
committed by GitHub
parent 035678d250
commit 0af1e512c2
10 changed files with 167 additions and 217 deletions

View File

@@ -53,12 +53,8 @@ public:
return this;
}
std::streambuf &operator*() {
return std::visit(
Visitor{
[](std::filebuf &file) -> std::streambuf & { return file; },
[](std::streambuf *buf) -> std::streambuf & { return *buf; }},
_file
);
auto *file = std::get_if<std::filebuf>(&_file);
return file ? *file : *std::get<std::streambuf *>(_file);
}
std::streambuf const &operator*() const {
// The non-`const` version does not perform any modifications, so it's okay.
@@ -71,32 +67,22 @@ public:
}
File *close() {
return std::visit(
Visitor{
[this](std::filebuf &file) {
// This is called by the destructor, and an explicit `close`
// shouldn't close twice.
_file.emplace<std::streambuf *>(nullptr);
return file.close() != nullptr;
},
[](std::streambuf *buf) { return buf != nullptr; },
},
_file
)
? this
: nullptr;
if (auto *file = std::get_if<std::filebuf>(&_file); file) {
// This is called by the destructor, and an explicit `close` shouldn't close twice.
_file.emplace<std::streambuf *>(nullptr);
if (file->close() != nullptr) {
return this;
}
} else if (std::get<std::streambuf *>(_file) != nullptr) {
return this;
}
return nullptr;
}
char const *c_str(std::string const &path) const {
return std::visit(
Visitor{
[&path](std::filebuf const &) { return path.c_str(); },
[](std::streambuf const *buf) {
return buf == std::cin.rdbuf() ? "<stdin>" : "<stdout>";
},
},
_file
);
return std::holds_alternative<std::filebuf>(_file) ? path.c_str()
: std::get<std::streambuf *>(_file) == std::cin.rdbuf() ? "<stdin>"
: "<stdout>";
}
};