45 struct UnknownSubCommand {};
64 void tabCompletion(std::vector<std::string>& tokens)
const override;
71 void setToken(
void* token_) { assert(!token); token = token_; }
72 [[nodiscard]]
void*
getToken()
const {
return token; }
75 template<
typename... Args>
78 executeSubCommandImpl(subCmd, std::forward<Args>(args)...);
79 }
catch (UnknownSubCommand&) {
80 unknownSubCommand(subCmd, std::forward<Args>(args)...);
89 template<
typename Func,
typename... Args>
90 void executeSubCommandImpl(std::string_view subCmd, std::string_view candidate, Func func, Args&&... args)
const {
91 if (subCmd == candidate) {
94 executeSubCommandImpl(subCmd, std::forward<Args>(args)...);
97 [[noreturn]]
void executeSubCommandImpl(std::string_view )
const {
98 throw UnknownSubCommand{};
101 template<
typename Func,
typename... Args>
102 void unknownSubCommand(std::string_view subCmd, std::string_view firstCandidate, Func , Args&&... args)
const {
103 unknownSubCommandImpl(
strCat(
"Unknown subcommand '", subCmd,
"'. Must be one of '", firstCandidate,
'\''),
104 std::forward<Args>(args)...);
106 template<
typename Func,
typename... Args>
107 void unknownSubCommandImpl(std::string message, std::string_view candidate, Func , Args&&... args)
const {
108 strAppend(message,
", '", candidate,
'\'');
109 unknownSubCommandImpl(message, std::forward<Args>(args)...);
112 template<
typename Func>
113 void unknownSubCommandImpl(std::string message, std::string_view lastCandidate, Func )
const {
114 strAppend(message,
" or '", lastCandidate,
"'.");
115 throw CommandException(message);
119 bool allowInEmptyMachine =
true;
120 void* token =
nullptr;