Есть такие штуковины (упрощенно):
struct StackItem{
};
template <class T>
struct StackValueItem:Base{
T value;
};
typedef std::vector<StackItem*> DataStack;
Есть метод класса:
RetType method(Type1 arg1,Type2 arg2);
Допустим последние два элемента DataStack это StackValueItem<Type1>* и StackValueItem<Type2>*.
Мне нужно "завернуть" вызов во что-то, что автоматом скастит элементы DataStack
к нужным типам, вызовет method, и уберёт из вектора 2 последних элемента,
и заменит на DataStack<RetType>*.
В принципе решение у меня есть, и оно работает.
Но получилось, что у меня храниться указатель на класс
с виртуальным методом, который потом вызывает метод по указателю.
Вся эта куча косвенности выглядит как горячая точка, по результатам профилирования.
Вот думаю, нельзя ли как-то это ускорить чуток.
Моё решение выглядит как-то так (DataStack тут мой класс, не вектор):
struct RuleHandlerBase{
virtual void handleRule(DataStack& stack,RuleEntry re)=0;
};
#define ARG(n,arg_type) ((StackValueItem<arg_type>&)*(stack.last[n])).value
template <class P,class RV,class A1,class A2>
struct RuleHandler2:RuleHandlerBase{
P* p;
RV (P::*method)(A1,A2);
RuleHandler2(P* argP,RV (P::*argMethod)(A1,A2)):p(argP),method(argMethod){}
void handleRule(DataStack& stack,RuleEntry re)
{
stack.replace(2,new StackValueItem<RV>((p->*method)(ARG(-1,A1),ARG(0,A2)),re));
}
};
template <class RV,class A1,class A2>
void add2(const SeqInfo& rule,RV (ImplType::*method)(A1,A2))
{
parseRule(rule).handler=new RuleHandler2<ImplType,RV,A1,A2>((ImplType*)this,method);
}
Классы и методы от 0 до стольки, сколько нужно.
Вызов addN выглядит так:
add2(SeqInfo("expr call","expr: expr tORBr- arglist tCRBr-",300),&ZParser::handleCall);
Я в курсе про boost::function. Но... Я пробовал chaiscript и примеры из boost::spirit.
На моей десктопной машинке примеры компилируются по несколько минут,
и компилятор (gcc) при этом съедает под гиг памяти. Как-то мне это не нравиться.
Опять таки, clang++ вообще попрехнулся chaiscript. Ошибка не влезла в один экран терминала...
Мне не нужно supergeneric решения, мне хватит конкретного решения конкретной задачи.
Ургументы методов и возвращаемые значения в большинстве своём указатели.