Skip to content

Instantly share code, notes, and snippets.

@piscisaureus
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save piscisaureus/b94c77e22c8db34a5d51 to your computer and use it in GitHub Desktop.
Save piscisaureus/b94c77e22c8db34a5d51 to your computer and use it in GitHub Desktop.
nni
#include <functional>
#include <iostream>
class JSAny {
void* substance;
};
class JSBool : public JSAny {
public:
JSBool() {}
static JSBool From(JSAny& v) {
JSBool b;
return b;
}
};
class JSInt : public JSAny {
public:
JSInt(){};
JSInt(int a){};
static JSInt From(JSAny& v) {
JSInt a;
return a;
}
};
class JSUndefined : public JSAny {
public:
JSUndefined(void){};
};
class JSArgumentList {
public:
JSAny any;
JSAny get(int index) { return any; }
size_t length() { return 0; }
};
template <typename T>
T convert(JSArgumentList& list, int& index) {
std::cout << index << std::endl;
return T::From(list.get(index++));
}
template <typename ReturnType, typename Function, typename... Arguments>
struct void_to_undefined {
static ReturnType Call(Function& function, Arguments&... arguments) {
return function(arguments...);
};
};
template <typename Function, typename... Arguments>
struct void_to_undefined<void, Function, Arguments...> {
static JSUndefined Call(Function& function, Arguments&... arguments) {
function(arguments...);
return JSUndefined();
};
};
template <typename ReturnType, typename... Arguments>
class JSFunction {
public:
typedef std::function<ReturnType(Arguments...)> ImplementationType;
typedef typename std::conditional<std::is_void<ReturnType>::value,
JSUndefined,
ReturnType>::type JSReturnType;
JSFunction(ImplementationType& func) : implementation(func) {}
JSReturnType operator()(Arguments&... arguments) {
return void_to_undefined<ReturnType,
ImplementationType,
Arguments...>::Call(implementation, arguments...);
};
JSAny RuntimeCall(JSArgumentList& arguments) {
int index = 0;
return operator()(convert<Arguments>(arguments, index)...);
};
ImplementationType implementation;
};
template <bool is_class, typename Callable>
struct callable_signature_helper {};
template <typename ReturnType, typename... Arguments>
struct callable_signature_helper<false, ReturnType (*)(Arguments...)> {
typedef std::function<ReturnType(Arguments...)> function;
typedef JSFunction<ReturnType, Arguments...> js_function;
};
template <typename Callable>
struct callable_signature_helper<true, Callable>
: public callable_signature_helper<true, decltype(&Callable::operator())> {
};
template <typename Class, typename ReturnType, typename... Arguments>
struct callable_signature_helper<true,
ReturnType (Class::*)(Arguments...) const> {
typedef std::function<ReturnType(Arguments...)> function;
typedef JSFunction<ReturnType, Arguments...> js_function;
};
template <typename Callable>
struct callable_signature
: public callable_signature_helper<std::is_class<Callable>::value,
Callable> {};
template <typename Callable>
typename callable_signature<Callable>::js_function function(Callable callable) {
return callable_signature<Callable>::js_function(
static_cast<typename callable_signature<Callable>::function>(callable));
}
JSInt Test2(JSBool a, JSInt b) {
std::cout << "hello2" << std::endl;
return 42;
}
class TestClass {
public:
static void Test3(JSBool a, JSInt b) { std::cout << "hello3" << std::endl; }
};
int main(int argc, const char** argv) {
auto fn1 = function([](JSBool a, JSInt b) -> JSInt {
std::cout << "hello" << std::endl;
return 42;
});
auto fn2 = function(Test2);
auto fn3 = function(TestClass::Test3);
JSArgumentList arguments;
fn1.RuntimeCall(arguments);
fn2.RuntimeCall(arguments);
fn3.RuntimeCall(arguments);
JSBool a;
JSInt b;
auto test1 = fn1(a, b);
auto test2 = fn2(a, b);
auto test3 = fn3(a, b);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment