Speech bubbles can point down right.
[scummvm-innocent.git] / common / func.h
blobdcad7ce6bfedcd2da2b9d65ccd9ea27ede247ce5
1 /* ScummVM - Graphic Adventure Engine
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * $URL$
22 * $Id$
25 #ifndef COMMON_FUNC_H
26 #define COMMON_FUNC_H
28 #include "common/scummsys.h"
30 namespace Common {
32 /**
33 * Generic unary function.
35 template<class Arg, class Result>
36 struct UnaryFunction {
37 typedef Arg ArgumenType;
38 typedef Result ResultType;
41 /**
42 * Generic binary function.
44 template<class Arg1, class Arg2, class Result>
45 struct BinaryFunction {
46 typedef Arg1 FirstArgumentType;
47 typedef Arg2 SecondArgumentType;
48 typedef Result ResultType;
51 /**
52 * Predicate to check for equallity of two data elements.
54 template<class T>
55 struct EqualTo : public BinaryFunction<T, T, bool> {
56 bool operator()(const T &x, const T &y) const { return x == y; }
59 /**
60 * Predicate to check for x being less than y.
62 template<class T>
63 struct Less : public BinaryFunction<T, T, bool> {
64 bool operator()(const T &x, const T &y) const { return x < y; }
67 /**
68 * Predicate to check for x being greater than y.
70 template<class T>
71 struct Greater : public BinaryFunction<T, T, bool> {
72 bool operator()(const T &x, const T &y) const { return x > y; }
75 template<class Op>
76 class Binder1st : public UnaryFunction<typename Op::SecondArgumentType, typename Op::ResultType> {
77 private:
78 Op _op;
79 typename Op::FirstArgumentType _arg1;
80 public:
81 Binder1st(const Op &op, typename Op::FirstArgumentType arg1) : _op(op), _arg1(arg1) {}
83 typename Op::ResultType operator()(typename Op::SecondArgumentType v) const {
84 return _op(_arg1, v);
88 /**
89 * Transforms a binary function object into an unary function object.
90 * To achieve that the first parameter is bound to the passed value t.
92 template<class Op>
93 inline Binder1st<Op> bind1st(const Op &op, typename Op::FirstArgumentType t) {
94 return Binder1st<Op>(op, t);
97 template<class Op>
98 class Binder2nd : public UnaryFunction<typename Op::FirstArgumentType, typename Op::ResultType> {
99 private:
100 Op _op;
101 typename Op::SecondArgumentType _arg2;
102 public:
103 Binder2nd(const Op &op, typename Op::SecondArgumentType arg2) : _op(op), _arg2(arg2) {}
105 typename Op::ResultType operator()(typename Op::FirstArgumentType v) const {
106 return _op(v, _arg2);
111 * Transforms a binary function object into an unary function object.
112 * To achieve that the first parameter is bound to the passed value t.
114 template<class Op>
115 inline Binder2nd<Op> bind2nd(const Op &op, typename Op::SecondArgumentType t) {
116 return Binder2nd<Op>(op, t);
119 template<class Arg, class Result>
120 class PointerToUnaryFunc : public UnaryFunction<Arg, Result> {
121 private:
122 Result (*_func)(Arg);
123 public:
124 typedef Result (*FuncType)(Arg);
126 PointerToUnaryFunc(const FuncType &func) : _func(func) {}
127 Result operator()(Arg v) const {
128 return _func(v);
132 template<class Arg1, class Arg2, class Result>
133 class PointerToBinaryFunc : public BinaryFunction<Arg1, Arg2, Result> {
134 private:
135 Result (*_func)(Arg1, Arg2);
136 public:
137 typedef Result (*FuncType)(Arg1, Arg2);
139 PointerToBinaryFunc(const FuncType &func) : _func(func) {}
140 Result operator()(Arg1 v1, Arg2 v2) const {
141 return _func(v1, v2);
146 * Creates an unary function object from a function pointer.
148 template<class Arg, class Result>
149 inline PointerToUnaryFunc<Arg, Result> ptr_fun(Result (*func)(Arg)) {
150 return PointerToUnaryFunc<Arg, Result>(func);
154 * Creates an binary function object from a function pointer.
156 template<class Arg1, class Arg2, class Result>
157 inline PointerToBinaryFunc<Arg1, Arg2, Result> ptr_fun(Result (*func)(Arg1, Arg2)) {
158 return PointerToBinaryFunc<Arg1, Arg2, Result>(func);
161 template<class Result, class T>
162 class MemFunc0 : public UnaryFunction<T *, Result> {
163 private:
164 Result (T::*_func)();
165 public:
166 typedef Result (T::*FuncType)();
168 MemFunc0(const FuncType &func) : _func(func) {}
169 Result operator()(T *v) const {
170 return (v->*_func)();
174 template<class Result, class T>
175 class ConstMemFunc0 : public UnaryFunction<T *, Result> {
176 private:
177 Result (T::*_func)() const;
178 public:
179 typedef Result (T::*FuncType)() const;
181 ConstMemFunc0(const FuncType &func) : _func(func) {}
182 Result operator()(const T *v) const {
183 return (v->*_func)();
187 template<class Result, class Arg, class T>
188 class MemFunc1 : public BinaryFunction<T *, Arg, Result> {
189 private:
190 Result (T::*_func)(Arg);
191 public:
192 typedef Result (T::*FuncType)(Arg);
194 MemFunc1(const FuncType &func) : _func(func) {}
195 Result operator()(T *v1, Arg v2) const {
196 return (v1->*_func)(v2);
200 template<class Result, class Arg, class T>
201 class ConstMemFunc1 : public BinaryFunction<T *, Arg, Result> {
202 private:
203 Result (T::*_func)(Arg) const;
204 public:
205 typedef Result (T::*FuncType)(Arg) const;
207 ConstMemFunc1(const FuncType &func) : _func(func) {}
208 Result operator()(const T *v1, Arg v2) const {
209 return (v1->*_func)(v2);
214 * Creates a unary function object from a class member function pointer.
215 * The parameter passed to the function object is the 'this' pointer to
216 * be used for the function call.
218 template<class Result, class T>
219 inline MemFunc0<Result, T> mem_fun(Result (T::*f)()) {
220 return MemFunc0<Result, T>(f);
224 * Creates a unary function object from a class member function pointer.
225 * The parameter passed to the function object is the 'this' pointer to
226 * be used for the function call.
228 template<class Result, class T>
229 inline ConstMemFunc0<Result, T> mem_fun(Result (T::*f)() const) {
230 return ConstMemFunc0<Result, T>(f);
234 * Creates a binary function object from a class member function pointer.
235 * The first parameter passed to the function object is the 'this' pointer to
236 * be used for the function call.
237 * The second one is the parameter passed to the member function.
239 template<class Result, class Arg, class T>
240 inline MemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg)) {
241 return MemFunc1<Result, Arg, T>(f);
245 * Creates a binary function object from a class member function pointer.
246 * The first parameter passed to the function object is the 'this' pointer to
247 * be used for the function call.
248 * The second one is the parameter passed to the member function.
250 template<class Result, class Arg, class T>
251 inline ConstMemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg) const) {
252 return ConstMemFunc1<Result, Arg, T>(f);
255 template<class Result, class T>
256 class MemFuncRef0 : public UnaryFunction<T &, Result> {
257 private:
258 Result (T::*_func)();
259 public:
260 typedef Result (T::*FuncType)();
262 MemFuncRef0(const FuncType &func) : _func(func) {}
263 Result operator()(T &v) const {
264 return (v.*_func)();
268 template<class Result, class T>
269 class ConstMemFuncRef0 : public UnaryFunction<T &, Result> {
270 private:
271 Result (T::*_func)() const;
272 public:
273 typedef Result (T::*FuncType)() const;
275 ConstMemFuncRef0(const FuncType &func) : _func(func) {}
276 Result operator()(const T &v) const {
277 return (v.*_func)();
281 template<class Result, class Arg, class T>
282 class MemFuncRef1 : public BinaryFunction<T &, Arg, Result> {
283 private:
284 Result (T::*_func)(Arg);
285 public:
286 typedef Result (T::*FuncType)(Arg);
288 MemFuncRef1(const FuncType &func) : _func(func) {}
289 Result operator()(T &v1, Arg v2) const {
290 return (v1.*_func)(v2);
294 template<class Result, class Arg, class T>
295 class ConstMemFuncRef1 : public BinaryFunction<T &, Arg, Result> {
296 private:
297 Result (T::*_func)(Arg) const;
298 public:
299 typedef Result (T::*FuncType)(Arg) const;
301 ConstMemFuncRef1(const FuncType &func) : _func(func) {}
302 Result operator()(const T &v1, Arg v2) const {
303 return (v1.*_func)(v2);
308 * Creates a unary function object from a class member function pointer.
309 * The parameter passed to the function object is the object instance to
310 * be used for the function call. Note unlike mem_fun, it takes a reference
311 * as parameter. Note unlike mem_fun, it takes a reference
312 * as parameter.
314 template<class Result, class T>
315 inline MemFuncRef0<Result, T> mem_fun_ref(Result (T::*f)()) {
316 return MemFuncRef0<Result, T>(f);
320 * Creates a unary function object from a class member function pointer.
321 * The parameter passed to the function object is the object instance to
322 * be used for the function call. Note unlike mem_fun, it takes a reference
323 * as parameter.
325 template<class Result, class T>
326 inline ConstMemFuncRef0<Result, T> mem_fun_Ref(Result (T::*f)() const) {
327 return ConstMemFuncRef0<Result, T>(f);
331 * Creates a binary function object from a class member function pointer.
332 * The first parameter passed to the function object is the object instance to
333 * be used for the function call. Note unlike mem_fun, it takes a reference
334 * as parameter.
335 * The second one is the parameter passed to the member function.
337 template<class Result, class Arg, class T>
338 inline MemFuncRef1<Result, Arg, T> mem_fun_ref(Result (T::*f)(Arg)) {
339 return MemFuncRef1<Result, Arg, T>(f);
343 * Creates a binary function object from a class member function pointer.
344 * The first parameter passed to the function object is the object instance to
345 * be used for the function call. Note unlike mem_fun, it takes a reference
346 * as parameter.
347 * The second one is the parameter passed to the member function.
349 template<class Result, class Arg, class T>
350 inline ConstMemFuncRef1<Result, Arg, T> mem_fun_ref(Result (T::*f)(Arg) const) {
351 return ConstMemFuncRef1<Result, Arg, T>(f);
354 // functor code
357 * Generic functor object for function objects without parameters.
359 * @see Functor1
361 template<class Res>
362 struct Functor0 {
363 virtual ~Functor0() {}
365 virtual bool isValid() const = 0;
366 virtual Res operator()() const = 0;
370 * Functor object for a class member function without parameter.
372 * Example creation:
374 * Foo bar;
375 * Functor0Mem<void, Foo> myFunctor(&bar, &Foo::myFunc);
377 * Example usage:
379 * myFunctor();
381 template<class Res, class T>
382 class Functor0Mem : public Functor0<Res> {
383 public:
384 typedef Res (T::*FuncType)();
386 Functor0Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
388 bool isValid() const { return _func != 0 && _t != 0; }
389 Res operator()() const {
390 return (_t->*_func)();
392 private:
393 mutable T *_t;
394 const FuncType _func;
398 * Generic functor object for unary function objects.
400 * A typical usage for an unary function object is for executing opcodes
401 * in a script interpreter. To achieve that one can create an Common::Array
402 * object with 'Functor1<Arg, Res> *' as type. Now after the right engine version
403 * has been determined and the opcode table to use is found one could easily
404 * add the opcode implementations like this:
406 * Common::Array<Functor1<ScriptState, void> *> opcodeTable;
407 * opcodeTable[0] = new Functor1Mem<ScriptState, void, MyEngine_v1>(&myEngine, &MyEngine_v1::o1_foo);
408 * opcodeTable[1] = new Functor1Mem<ScriptState, void, MyEngine_v2>(&myEngine, &MyEngine_v2::o2_foo);
409 * // unimplemented/unused opcode
410 * opcodeTable[2] = 0;
411 * etc.
413 * This makes it easy to add member functions of different classes as
414 * opcode functions to the function table. Since with the generic
415 * Functor1<ScriptState, void> object the only requirement for an
416 * function to be used is 'ScriptState' as argument and 'void' as return
417 * value.
419 * Now for calling the opcodes one has simple to do:
420 * if (opcodeTable[opcodeNum] && opcodeTable[opcodeNum]->isValid())
421 * (*opcodeTable[opcodeNum])(scriptState);
422 * else
423 * warning("Unimplemented opcode %d", opcodeNum);
425 * If you want to see an real world example check the kyra engine.
426 * Files: engines/kyra/script.cpp and .h and engine/kyra/script_*.cpp
427 * are interesting for that matter.
429 template<class Arg, class Res>
430 struct Functor1 : public Common::UnaryFunction<Arg, Res> {
431 virtual ~Functor1() {}
433 virtual bool isValid() const = 0;
434 virtual Res operator()(Arg) const = 0;
438 * Functor object for an unary class member function.
439 * Usage is like with Functor0Mem. The resulting functor object
440 * will take one parameter though.
442 * @see Functor0Mem
444 template<class Arg, class Res, class T>
445 class Functor1Mem : public Functor1<Arg, Res> {
446 public:
447 typedef Res (T::*FuncType)(Arg);
449 Functor1Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
451 bool isValid() const { return _func != 0 && _t != 0; }
452 Res operator()(Arg v1) const {
453 return (_t->*_func)(v1);
455 private:
456 mutable T *_t;
457 const FuncType _func;
461 * Generic functor object for binary function objects.
463 * @see Functor1
465 template<class Arg1, class Arg2, class Res>
466 struct Functor2 : public Common::BinaryFunction<Arg1, Arg2, Res> {
467 virtual ~Functor2() {}
469 virtual bool isValid() const = 0;
470 virtual Res operator()(Arg1, Arg2) const = 0;
474 * Functor object for a binary function.
476 * @see Functor2Mem
478 template<class Arg1, class Arg2, class Res>
479 class Functor2Fun : public Functor2<Arg1, Arg2, Res> {
480 public:
481 typedef Res (*FuncType)(Arg1, Arg2);
483 Functor2Fun(const FuncType func) : _func(func) {}
485 bool isValid() const { return _func != 0; }
486 Res operator()(Arg1 v1, Arg2 v2) const {
487 return (*_func)(v1, v2);
489 private:
490 const FuncType _func;
494 * Functor object for a binary class member function.
495 * Usage is like with Functor0Mem. The resulting functor object
496 * will take two parameter though.
498 * @see Functor0Mem
500 template<class Arg1, class Arg2, class Res, class T>
501 class Functor2Mem : public Functor2<Arg1, Arg2, Res> {
502 public:
503 typedef Res (T::*FuncType)(Arg1, Arg2);
505 Functor2Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
507 bool isValid() const { return _func != 0 && _t != 0; }
508 Res operator()(Arg1 v1, Arg2 v2) const {
509 return (_t->*_func)(v1, v2);
511 private:
512 mutable T *_t;
513 const FuncType _func;
517 * Base template for hash functor objects, used by HashMap.
518 * This needs to be specialized for every type that you need to hash.
520 template<typename T> struct Hash;
523 #define GENERATE_TRIVIAL_HASH_FUNCTOR(T) \
524 template<> struct Hash<T> : public UnaryFunction<T, uint> { \
525 uint operator()(T val) const { return (uint)val; } \
528 GENERATE_TRIVIAL_HASH_FUNCTOR(bool);
529 GENERATE_TRIVIAL_HASH_FUNCTOR(char);
530 GENERATE_TRIVIAL_HASH_FUNCTOR(signed char);
531 GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned char);
532 GENERATE_TRIVIAL_HASH_FUNCTOR(short);
533 GENERATE_TRIVIAL_HASH_FUNCTOR(int);
534 GENERATE_TRIVIAL_HASH_FUNCTOR(long);
535 GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned short);
536 GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned int);
537 GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned long);
539 #undef GENERATE_TRIVIAL_HASH_FUNCTOR
541 } // End of namespace Common
543 #endif