#pragma once #include #include #include #include #include #include enum class PatternType { FixedWord, AnyWord, AnyWords }; struct Pattern { PatternType type; std::string fixed_word; }; using Callback = std::variant&)>, std::function&)>>; class Parser { public: void AddRule(const std::vector& pattern, const auto& callback, bool find_in_suggestion = true) { if constexpr (std::is_same_v< decltype(callback(std::declval&>())), void>) { AddRuleImpl(pattern, std::function&)>(callback), find_in_suggestion); } else { AddRuleImpl(pattern, std::function&)>(callback), find_in_suggestion); } } void Parse(int argc, char* argv[]) const; std::vector GetPossibleAdditions(int argc, char* argv[]) const; std::vector GetPossibleAdditions(const std::vector&) const; private: void AddRuleImpl(const std::vector& pattern, const Callback& callback, bool find_in_suggestion); bool Match(const std::vector& pattern, const std::vector& args) const; private: struct Rule { Rule(const std::vector& pattern, Callback callback, bool find_in_suggestion) : pattern(pattern), callback(callback), find_in_suggestion(find_in_suggestion) {} std::vector pattern; Callback callback; bool find_in_suggestion; }; std::vector rules_; }; std::vector MakePattern( std::initializer_list> elements);