Skip to content
Permalink
master
Go to file
 
 
Cannot retrieve contributors at this time
108 lines (91 sloc) 2.87 KB
#include "core/typeconv/typeconv.hpp"
#include <cassert>
#include <vector>
typedef std::vector<Type> TypeTable;
typedef std::vector<void*> Functions;
struct _opaque_dispatcher {};
class Dispatcher: public _opaque_dispatcher {
public:
Dispatcher(TypeManager *tm, int argct): argct(argct), tm(tm) { }
void addDefinition(Type args[], void *callable) {
overloads.reserve(argct + overloads.size());
for (int i=0; i<argct; ++i) {
overloads.push_back(args[i]);
}
functions.push_back(callable);
}
void* resolve(Type sig[], int &matches, bool allow_unsafe,
bool exact_match_required) {
const int ovct = functions.size();
int selected;
matches = 0;
if (0 == ovct) {
// No overloads registered
return NULL;
}
if (argct == 0) {
// Nullary function: trivial match on first overload
matches = 1;
selected = 0;
}
else {
matches = tm->selectOverload(sig, &overloads[0], selected, argct,
ovct, allow_unsafe,
exact_match_required);
}
if (matches == 1) {
return functions[selected];
}
return NULL;
}
int count() const { return functions.size(); }
void clear() {
functions.clear();
overloads.clear();
}
private:
const int argct;
TypeManager *tm;
// An array of overloads
Functions functions;
// A flattened array of argument types to all overloads
// (invariant: sizeof(overloads) == argct * sizeof(functions))
TypeTable overloads;
};
#include "_dispatcher.h"
dispatcher_t *
dispatcher_new(void *tm, int argct){
return new Dispatcher(static_cast<TypeManager*>(tm), argct);
}
void
dispatcher_clear(dispatcher_t *obj) {
Dispatcher *disp = static_cast<Dispatcher*>(obj);
disp->clear();
}
void
dispatcher_del(dispatcher_t *obj) {
Dispatcher *disp = static_cast<Dispatcher*>(obj);
delete disp;
}
void
dispatcher_add_defn(dispatcher_t *obj, int tys[], void* callable) {
assert(sizeof(int) == sizeof(Type) &&
"Type should be representable by an int");
Dispatcher *disp = static_cast<Dispatcher*>(obj);
Type *args = reinterpret_cast<Type*>(tys);
disp->addDefinition(args, callable);
}
void*
dispatcher_resolve(dispatcher_t *obj, int sig[], int *count, int allow_unsafe,
int exact_match_required) {
Dispatcher *disp = static_cast<Dispatcher*>(obj);
Type *args = reinterpret_cast<Type*>(sig);
void *callable = disp->resolve(args, *count, (bool) allow_unsafe,
(bool) exact_match_required);
return callable;
}
int
dispatcher_count(dispatcher_t *obj) {
Dispatcher *disp = static_cast<Dispatcher*>(obj);
return disp->count();
}
You can’t perform that action at this time.