This repository has been archived by the owner on Oct 28, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 67
Optional arguments to Opt using std::optional #89
Comments
My current work around is to use a class with a set of stream operators. edited slightly to only show the logging namespace utils {
// in utils.hxx
class log {
public:
log() = default;
explicit log(std::ostream& os)
: m_log{os.rdbuf()} {}
explicit log(fs::path const& path)
: m_log_{path}
, m_log{m_log_.rdbuf()} {}
template <typename T>
friend auto inline operator<<(utils::log& log, T const& value) -> utils::log& {
log.m_log << value;
return log;
}
friend auto operator>>(std::istream& is, log& log) -> std::istream&;
private:
std::ofstream m_log_{};
std::ostream m_log{nullptr};
};
// in utils.cxx
auto operator>>(std::istream& is, log& log) -> std::istream& {
auto buf = std::string{};
is >> buf;
// check if boolean value
auto const static negative = std::array{"0"s, "false"s, "off"s, "n"s, "no"s};
auto const static positive = std::array{"1"s, "true"s, "on"s, "y"s, "yes"s};
auto boolean = buf;
std::transform(std::begin(boolean), std::end(boolean), std::begin(boolean),
[](unsigned char c) { return std::tolower(c); });
if (std::find(std::begin(negative), std::end(negative), boolean) != std::end(negative)) {
// disable logging
} else if (std::find(std::begin(positive), std::end(positive), boolean) != std::end(positive)) {
// enable logging to stderr
log.m_log.rdbuf(std::clog.rdbuf());
} else {
// enable logging to file
auto const filename = fs::path{buf};
log.m_log_.open(filename);
log.m_log.rdbuf(log.m_log_.rdbuf());
}
return is;
}
} // namespace utils
// relevant bit of parser
bool m_help{false};
utils::log m_log{};
auto args = clara::Help(m_help)
| clara::Opt{m_log, "false|true|filename"s}["-l"s]["--log"s](
"<false> disable logging\n"
"<true> enable logging to stderr\n"
"<filename> enable logging to filename\t{false}"s); As you can see it's not quite ideal; I also have to call it |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
There is code to handle
std::optional
viaCLARA_CONFIG_OPTIONAL_TYPE
; howeverOpt
still is expecting an argument if none is given.For example for logging:
./program
, run with no logging (default),./program -l
enable logging,./program -l file.log
enable logging to named file.This would make sense to use
std::optional
here.For example, the default will not do anything; giving the "flag"
-l
will act like a pass the log through tostd::clog
; giving the optional with a filename-l /path/to/file.log
will pass through to the/path/to/file.log
.The text was updated successfully, but these errors were encountered: