Created
October 19, 2020 05:54
-
-
Save Cylix/723c89fa73cd1fa9f28e3548644cc8ee to your computer and use it in GitHub Desktop.
Reflection in C++14 - Reflection #1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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