1 #ifndef SHAREDDATALAYER_CLI_COMMANDMAP_HPP
2 #define SHAREDDATALAYER_CLI_COMMANDMAP_HPP
10 #include <boost/program_options.hpp>
11 #include <sdl/exception.hpp>
13 namespace shareddatalayer
20 class CommandNameAlreadyRegistered;
22 class UnknownCommandName;
24 class CategoryOffsetAlreadyRegistered;
36 using CommandFunction = std::function<int(std::ostream& out,
38 const boost::program_options::variables_map& params)>;
40 boost::program_options::options_description&
41 registerCommand(const std::string& commandName,
42 const std::string& shortHelp,
43 const std::string& longHelp,
44 const CommandFunction& commandFunction,
48 std::vector<std::string> getCommandNames() const;
50 const boost::program_options::options_description&
51 getCommandOptions(const std::string& commandName) const;
53 int execute(const std::string& commandName,
56 const boost::program_options::variables_map& params,
59 void shortHelp(std::ostream& out) const;
61 void longHelp(std::ostream& out, const std::string& commandName) const;
63 static CommandMap& getCommandMap() noexcept;
65 CommandMap(const CommandMap&) = delete;
66 CommandMap(CommandMap&&) = delete;
67 CommandMap& operator = (const CommandMap&) = delete;
68 CommandMap& operator = (CommandMap&&) = delete;
73 std::map<std::string, Info> map;
74 using CategoryKey = std::pair<Category, int>;
75 std::map<CategoryKey, std::string> categoryMap;
78 class CommandMap::CommandNameAlreadyRegistered: public Exception
81 explicit CommandNameAlreadyRegistered(const std::string& commandName);
84 class CommandMap::UnknownCommandName: public Exception
87 explicit UnknownCommandName(const std::string& commandName);
90 class CommandMap::CategoryOffsetAlreadyRegistered: public Exception
93 CategoryOffsetAlreadyRegistered(const std::string& commandName, int offset);
98 #define AUTO_REGISTER_COMMAND_XTOKENPASTE(x, y) x ## y
99 #define AUTO_REGISTER_COMMAND_TOKENPASTE(x, y) AUTO_REGISTER_COMMAND_XTOKENPASTE(x, y)
101 #define AUTO_REGISTER_COMMAND(_function, _name, _shortHelp, _longHelp, _category, _categoryOffset, ...) \
104 struct AUTO_REGISTER_COMMAND_TOKENPASTE(AutoRegister, __LINE__) \
106 AUTO_REGISTER_COMMAND_TOKENPASTE(AutoRegister, __LINE__)() \
108 ::shareddatalayer::cli::CommandMap::getCommandMap().registerCommand(_name, _shortHelp, _longHelp, _function, _category, _categoryOffset).add_options() \
111 ~AUTO_REGISTER_COMMAND_TOKENPASTE(AutoRegister, __LINE__)() { } \
113 AUTO_REGISTER_COMMAND_TOKENPASTE(AutoRegister, __LINE__) AUTO_REGISTER_COMMAND_TOKENPASTE(autoRegister, __LINE__); \