Skip to content

Instantly share code, notes, and snippets.

@takiyu
Created April 19, 2018 04:59
Show Gist options
  • Save takiyu/448ea00414f7b89519d78b95f3cbf6b7 to your computer and use it in GitHub Desktop.
Save takiyu/448ea00414f7b89519d78b95f3cbf6b7 to your computer and use it in GitHub Desktop.
Function node which accept any type of variable.
#include <iostream>
#include <vector>
#include <memory>
#include <typeinfo>
#include <cstring>
class Variable {
public:
template<typename T, typename... Args>
void create(Args... args) {
set(std::make_shared<T>(args...));
}
template<typename T>
void set(std::shared_ptr<T> v) {
data = v;
type = &typeid(T); // The lifetime extends to the end of the program.
}
template<typename T>
std::shared_ptr<T> getWriter() {
if (*type != typeid(T)) {
// Create by force
create<T>();
}
return std::static_pointer_cast<T>(data);
}
template<typename T>
std::shared_ptr<T> getReader() const {
if (*type != typeid(T)) {
// Invalid type cast
std::cerr << "Invalid cast (" << type->name() << " vs "
<< typeid(T).name() << ")" << std::endl;
return std::make_shared<T>();
}
return std::static_pointer_cast<T>(data);
}
private:
std::shared_ptr<void> data;
const std::type_info *type = &typeid(void);
};
class FunctionNode {
public:
virtual void build(const std::vector<Variable *> &args) = 0;
virtual void apply() = 0;
};
class Add : public FunctionNode {
public:
void build(const std::vector<Variable*> &args) {
if (args.size() != 3) {
std::cerr << "Invalid arguments" << std::endl;
return;
}
a = args[0]->getReader<int>();
b = args[1]->getReader<int>();
c = args[2]->getWriter<int>();
}
void apply() {
*c = *a + *b;
}
private:
std::shared_ptr<int> a, b, c;
};
int main(int argc, char const* argv[]) {
Variable v3;
Add add;
FunctionNode *node = &add;
{
// Create with variable creation
Variable v1, v2;
v1.create<int>(123);
v2.create<int>(456);
// Correct cast
std::cout << *(v1.getReader<int>()) << std::endl;
std::cout << *(v2.getReader<int>()) << std::endl;
node->build({&v1, &v2, &v3});
}
node->apply();
std::cout << *(v3.getReader<int>()) << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment