1#ifndef PLUGINS_PLUGIN_H
2#define PLUGINS_PLUGIN_H
5#include "plugin_info.h"
6#include "raw_registry.h"
8#include "downward/utils/strings.h"
9#include "downward/utils/system.h"
10#include "downward/utils/tuples.h"
22namespace downward::cli::plugins {
28 std::string subcategory;
29 std::vector<ArgumentInfo> arguments;
30 std::vector<PropertyInfo> properties;
31 std::vector<LanguageSupportInfo> language_support;
32 std::vector<NoteInfo> notes;
35 Feature(
const Type& type,
const std::string& key);
36 virtual ~Feature() =
default;
37 Feature(
const Feature&) =
delete;
40 construct(
const Options& opts, const ::utils::Context& context)
const = 0;
46 const std::string& key,
47 const std::string& help =
"",
48 const std::string& default_value =
"",
49 const Bounds& bounds = Bounds::unlimited(),
50 bool lazy_construction =
false);
54 const std::string& key,
55 const std::string& help =
"",
56 const std::string& default_value =
"",
57 bool lazy_construction =
false);
59 void document_subcategory(
const std::string& subcategory);
60 void document_title(
const std::string& title);
61 void document_synopsis(
const std::string& note);
63 document_property(
const std::string& property,
const std::string& note);
64 void document_language_support(
65 const std::string& feature,
66 const std::string& note);
68 const std::string& title,
69 const std::string& note,
70 bool long_text =
false);
72 const Type& get_type()
const;
73 std::string get_key()
const;
74 std::string get_title()
const;
75 std::string get_synopsis()
const;
76 std::string get_subcategory()
const;
77 const std::vector<ArgumentInfo>& get_arguments()
const;
78 const std::vector<PropertyInfo>& get_properties()
const;
79 const std::vector<LanguageSupportInfo>& get_language_support()
const;
80 const std::vector<NoteInfo>& get_notes()
const;
83template <
typename Constructed>
84class FeatureWithDefault :
public Feature {
86 using Feature::Feature;
87 virtual std::shared_ptr<Constructed>
88 create_component(
const Options& options, const ::utils::Context&)
const
90 return std::make_shared<Constructed>(options);
94template <
typename Constructed>
95class FeatureWithoutDefault :
public Feature {
97 using Feature::Feature;
98 virtual std::shared_ptr<Constructed>
99 create_component(
const Options&, const ::utils::Context&)
const = 0;
102template <
typename Constructed>
103using FeatureAuto =
typename std::conditional<
104 std::is_constructible<Constructed, const Options&>::value,
105 FeatureWithDefault<Constructed>,
106 FeatureWithoutDefault<Constructed>>::type;
108template <
typename Base,
typename Constructed>
109class TypedFeature :
public FeatureAuto<Constructed> {
110 using BasePtr = std::shared_ptr<Base>;
112 std::is_base_of<Base, Constructed>::value,
113 "Constructed must derive from Base");
116 TypedFeature(
const std::string& key)
117 : FeatureAuto<Constructed>(
118 TypeRegistry::instance()->get_type<BasePtr>(),
123 std::any construct(
const Options& options, const ::utils::Context& context)
126 std::shared_ptr<Base> ptr = this->create_component(options, context);
127 return std::any(ptr);
137template <
typename T,
typename... Arguments>
138std::shared_ptr<T> make_shared_from_arg_tuples(Arguments... arguments)
141 [](
auto&&... flattened_args) {
142 return std::make_shared<T>(
143 std::forward<
decltype(flattened_args)>(flattened_args)...);
145 ::utils::flatten_tuple(
146 std::tuple<Arguments...>(std::forward<Arguments>(arguments)...)));
152 virtual ~Plugin() =
default;
153 Plugin(
const Plugin&) =
delete;
154 virtual std::shared_ptr<Feature> create_feature()
const = 0;
158class FeaturePlugin :
public Plugin {
164 virtual std::shared_ptr<Feature> create_feature()
const override
166 return std::make_shared<T>();
174class CategoryPlugin {
175 std::type_index pointer_type;
176 std::string class_name;
184 std::string category_name;
190 std::string synopsis;
200 bool can_be_bound_to_variable;
204 std::type_index pointer_type,
205 const std::string& class_name,
206 const std::string& category_name);
207 virtual ~CategoryPlugin() =
default;
208 CategoryPlugin(
const CategoryPlugin&) =
delete;
210 void document_synopsis(
const std::string& synopsis);
211 void allow_variable_binding();
213 std::type_index get_pointer_type()
const;
214 std::string get_category_name()
const;
215 std::string get_class_name()
const;
216 std::string get_synopsis()
const;
217 bool supports_variable_binding()
const;
221class TypedCategoryPlugin :
public CategoryPlugin {
223 TypedCategoryPlugin(
const std::string& category_name)
225 typeid(
std::shared_ptr<T>),
226 typeid(
std::shared_ptr<T>).name(),
232class SubcategoryPlugin {
233 std::string subcategory_name;
235 std::string synopsis;
238 SubcategoryPlugin(
const std::string& subcategory);
240 void document_title(
const std::string& title);
241 void document_synopsis(
const std::string& synopsis);
243 std::string get_subcategory_name()
const;
244 std::string get_title()
const;
245 std::string get_synopsis()
const;
249 std::type_index type;
250 std::string class_name;
255 std::type_index type,
256 const std::string& class_name,
257 std::initializer_list<std::pair<std::string, std::string>> enum_values);
259 std::type_index get_type()
const;
260 std::string get_class_name()
const;
261 const EnumInfo& get_enum_info()
const;
265class TypedEnumPlugin :
public EnumPlugin {
268 std::initializer_list<std::pair<std::string, std::string>> enum_values)
269 : EnumPlugin(typeid(T), typeid(
std::shared_ptr<T>).name(), enum_values)
275void Feature::add_option(
276 const std::string& key,
277 const std::string& help,
278 const std::string& default_value,
279 const Bounds& bounds,
280 bool lazy_construction)
282 arguments.emplace_back(
285 TypeRegistry::instance()->get_type<T>(),
292void Feature::add_list_option(
293 const std::string& key,
294 const std::string& help,
295 const std::string& default_value,
296 bool lazy_construction)
298 add_option<std::vector<T>>(