, , , , , . , , , , , , , .
, , dispatch, -. , , . , , , , .
memoization, Memo, , CacheWrapper, .
#include <algorithm>
#include <map>
#include <utility>
#include <vector>
namespace {
template <typename Type1, typename Type2>
class FirstEq {
FirstType value;
public:
typedef std::pair<Type1, Type2> ArgType;
FirstEq(Type1 t) : value(t) {}
bool operator()(const ArgType& rhs) const {
return value == rhs.first;
}
};
};
template <typename T>
class Memo {
typedef void (T::*TMemFun)(void);
typedef std::vector< std::pair<TMemFun, void*> > FuncRecords;
T memoized;
FuncRecords funcCalls;
public:
Memo(T t) : memoized(t) {}
template <typename ReturnType, typename ArgType>
ReturnType dispatch(ReturnType (T::* memFun)(ArgType), ArgType arg) {
typedef std::map<ArgType, ReturnType> Record;
typename FuncRecords::iterator recIter =
find_if(funcCalls.begin(),
funcCalls.end(),
FirstEq<TMemFun, void*>(
reinterpret_cast<TMemFun>(memFun)));
if (recIter == funcCalls.end()) {
funcCalls.push_back(
std::make_pair(reinterpret_cast<TMemFun>(memFun),
static_cast<void*>(new Record)));
recIter = --funcCalls.end();
}
Record* rec = static_cast<Record*>(
recIter->second);
typename Record::iterator callIter = rec->lower_bound(arg);
if (callIter == rec->end() || callIter->first != arg) {
callIter = rec->insert(callIter,
std::make_pair(arg,
(memoized.*memFun)(arg)));
}
return callIter->second;
}
};
, :
#include <iostream>
#include <sstream>
#include "Memo.h"
using namespace std;
struct C {
int three(int x) {
cout << "Called three(" << x << ")" << endl;
return 3;
}
double square(float x) {
cout << "Called square(" << x << ")" << endl;
return x * x;
}
};
int main(void) {
C c;
Memo<C> m(c);
cout << m.dispatch(&C::three, 1) << endl;
cout << m.dispatch(&C::three, 2) << endl;
cout << m.dispatch(&C::three, 1) << endl;
cout << m.dispatch(&C::three, 2) << endl;
cout << m.dispatch(&C::square, 2.3f) << endl;
cout << m.dispatch(&C::square, 2.3f) << endl;
return 0;
}
(MacOS 10.4.11 g++ 4.0.1):
Called three(1)
3
Called three(2)
3
3
3
Called square(2.3)
5.29
5.29
- , 1 . , 0 , 2, 3 . . , . , Boost Tuple library. 10 , .
- - FirstEq find_if . , , , , .
- , , ..
void, , ! - - wrapped, - , (). , , .
- , ( ) .
- , , - , ++. ( , !) , .
- , -- ++. , , , -, .