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.
28 #include "common/scummsys.h"
33 * Generic unary function.
35 template<class Arg
, class Result
>
36 struct UnaryFunction
{
37 typedef Arg ArgumenType
;
38 typedef Result ResultType
;
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
;
52 * Predicate to check for equallity of two data elements.
55 struct EqualTo
: public BinaryFunction
<T
, T
, bool> {
56 bool operator()(const T
&x
, const T
&y
) const { return x
== y
; }
60 * Predicate to check for x being less than y.
63 struct Less
: public BinaryFunction
<T
, T
, bool> {
64 bool operator()(const T
&x
, const T
&y
) const { return x
< y
; }
68 * Predicate to check for x being greater than y.
71 struct Greater
: public BinaryFunction
<T
, T
, bool> {
72 bool operator()(const T
&x
, const T
&y
) const { return x
> y
; }
76 class Binder1st
: public UnaryFunction
<typename
Op::SecondArgumentType
, typename
Op::ResultType
> {
79 typename
Op::FirstArgumentType _arg1
;
81 Binder1st(const Op
&op
, typename
Op::FirstArgumentType arg1
) : _op(op
), _arg1(arg1
) {}
83 typename
Op::ResultType
operator()(typename
Op::SecondArgumentType v
) const {
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.
93 inline Binder1st
<Op
> bind1st(const Op
&op
, typename
Op::FirstArgumentType t
) {
94 return Binder1st
<Op
>(op
, t
);
98 class Binder2nd
: public UnaryFunction
<typename
Op::FirstArgumentType
, typename
Op::ResultType
> {
101 typename
Op::SecondArgumentType _arg2
;
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.
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
> {
122 Result (*_func
)(Arg
);
124 typedef Result (*FuncType
)(Arg
);
126 PointerToUnaryFunc(const FuncType
&func
) : _func(func
) {}
127 Result
operator()(Arg v
) const {
132 template<class Arg1
, class Arg2
, class Result
>
133 class PointerToBinaryFunc
: public BinaryFunction
<Arg1
, Arg2
, Result
> {
135 Result (*_func
)(Arg1
, Arg2
);
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
> {
164 Result (T::*_func
)();
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
> {
177 Result (T::*_func
)() const;
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
> {
190 Result (T::*_func
)(Arg
);
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
> {
203 Result (T::*_func
)(Arg
) const;
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
> {
258 Result (T::*_func
)();
260 typedef Result (T::*FuncType
)();
262 MemFuncRef0(const FuncType
&func
) : _func(func
) {}
263 Result
operator()(T
&v
) const {
268 template<class Result
, class T
>
269 class ConstMemFuncRef0
: public UnaryFunction
<T
&, Result
> {
271 Result (T::*_func
)() const;
273 typedef Result (T::*FuncType
)() const;
275 ConstMemFuncRef0(const FuncType
&func
) : _func(func
) {}
276 Result
operator()(const T
&v
) const {
281 template<class Result
, class Arg
, class T
>
282 class MemFuncRef1
: public BinaryFunction
<T
&, Arg
, Result
> {
284 Result (T::*_func
)(Arg
);
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
> {
297 Result (T::*_func
)(Arg
) const;
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
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
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
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
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
);
357 * Generic functor object for function objects without parameters.
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.
375 * Functor0Mem<void, Foo> myFunctor(&bar, &Foo::myFunc);
381 template<class Res
, class T
>
382 class Functor0Mem
: public Functor0
<Res
> {
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
)();
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;
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
419 * Now for calling the opcodes one has simple to do:
420 * if (opcodeTable[opcodeNum] && opcodeTable[opcodeNum]->isValid())
421 * (*opcodeTable[opcodeNum])(scriptState);
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.
444 template<class Arg
, class Res
, class T
>
445 class Functor1Mem
: public Functor1
<Arg
, Res
> {
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
);
457 const FuncType _func
;
461 * Generic functor object for binary function objects.
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.
478 template<class Arg1
, class Arg2
, class Res
>
479 class Functor2Fun
: public Functor2
<Arg1
, Arg2
, Res
> {
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
);
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.
500 template<class Arg1
, class Arg2
, class Res
, class T
>
501 class Functor2Mem
: public Functor2
<Arg1
, Arg2
, Res
> {
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
);
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