Skip to content

Instantly share code, notes, and snippets.

@Cylix
Created October 19, 2020 05:54
Show Gist options
  • Save Cylix/723c89fa73cd1fa9f28e3548644cc8ee to your computer and use it in GitHub Desktop.
Save Cylix/723c89fa73cd1fa9f28e3548644cc8ee to your computer and use it in GitHub Desktop.
Reflection in C++14 - Reflection #1
class reflection_manager {
public:
~reflection_manager(void) = default;
reflection_manager(const reflection_manager&) = delete;
reflection_manager& operator=(const reflection_manager&) = delete;
static reflection_manager& get_instance(void) {
static reflection_manager instance;
return instance;
}
void register_reflectable(reflectable_base& r) {
// store the reflectable
this->reflectables.push_back({ r });
}
template <typename ReturnType, typename... Params>
ReturnType reflect(const std::string& class_name, const std::string& function_name, Params... params) {
for (const auto& reflectable : this->reflectables)
if (reflectable.get().get_name() == class_name) {
//! get the member functions of the class
const auto& functions = reflectable.get().get_functions();
//! iterate over the functions to find the one we are interested in
for (const auto& f : functions)
if (f.first == function_name) {
//! dynamic pointer cast to ensure type safety
auto function_with_real_type = std::dynamic_pointer_cast<function<ReturnType(Params...)>>(f.second);
//! type mismatch if dynamic_cast has failed
if (not function_with_real_type)
throw std::runtime_error(class_name + "::" + function_name + " called with the wrong signature");
//! call our function: reflection is done!
return (*function_with_real_type)(params...);
}
throw std::runtime_error(class_name + "::" + function_name + " is not registered for reflection");
}
throw std::runtime_error(class_name + " is not registered for reflection");
}
private:
reflection_manager(void) = default;
std::vector<std::reference_wrapper<reflectable_base>> reflectables;
};
int main(void) {
reflection_manager::get_instance().reflect<void, int, double>("SomeClass", "some_fct", 1, 4.2); // will call SomeClass().some_fct(1, 4.2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment