func.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. /* ScummVM Tools
  2. *
  3. * ScummVM Tools is the legal property of its developers, whose
  4. * names are too numerous to list here. Please refer to the
  5. * COPYRIGHT file distributed with this source distribution.
  6. *
  7. * Additionally this file is based on the ScummVM source code.
  8. * Copyright information for the ScummVM source code is
  9. * available in the COPYRIGHT file of the ScummVM source
  10. * distribution.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License
  14. * as published by the Free Software Foundation; either version 2
  15. * of the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  25. */
  26. #ifndef COMMON_FUNC_H
  27. #define COMMON_FUNC_H
  28. #include "common/scummsys.h"
  29. namespace Common {
  30. /**
  31. * Generic unary function.
  32. */
  33. template<class Arg, class Result>
  34. struct UnaryFunction {
  35. typedef Arg ArgumenType;
  36. typedef Result ResultType;
  37. };
  38. /**
  39. * Generic binary function.
  40. */
  41. template<class Arg1, class Arg2, class Result>
  42. struct BinaryFunction {
  43. typedef Arg1 FirstArgumentType;
  44. typedef Arg2 SecondArgumentType;
  45. typedef Result ResultType;
  46. };
  47. /**
  48. * Predicate to check for equallity of two data elements.
  49. */
  50. template<class T>
  51. struct EqualTo : public BinaryFunction<T, T, bool> {
  52. bool operator()(const T &x, const T &y) const { return x == y; }
  53. };
  54. /**
  55. * Predicate to check for x being less than y.
  56. */
  57. template<class T>
  58. struct Less : public BinaryFunction<T, T, bool> {
  59. bool operator()(const T &x, const T &y) const { return x < y; }
  60. };
  61. /**
  62. * Predicate to check for x being greater than y.
  63. */
  64. template<class T>
  65. struct Greater : public BinaryFunction<T, T, bool> {
  66. bool operator()(const T &x, const T &y) const { return x > y; }
  67. };
  68. template<class Op>
  69. class Binder1st : public UnaryFunction<typename Op::SecondArgumentType, typename Op::ResultType> {
  70. private:
  71. Op _op;
  72. typename Op::FirstArgumentType _arg1;
  73. public:
  74. Binder1st(const Op &op, typename Op::FirstArgumentType arg1) : _op(op), _arg1(arg1) {}
  75. typename Op::ResultType operator()(typename Op::SecondArgumentType v) const {
  76. return _op(_arg1, v);
  77. }
  78. };
  79. /**
  80. * Transforms a binary function object into an unary function object.
  81. * To achieve that the first parameter is bound to the passed value t.
  82. */
  83. template<class Op>
  84. inline Binder1st<Op> bind1st(const Op &op, typename Op::FirstArgumentType t) {
  85. return Binder1st<Op>(op, t);
  86. }
  87. template<class Op>
  88. class Binder2nd : public UnaryFunction<typename Op::FirstArgumentType, typename Op::ResultType> {
  89. private:
  90. Op _op;
  91. typename Op::SecondArgumentType _arg2;
  92. public:
  93. Binder2nd(const Op &op, typename Op::SecondArgumentType arg2) : _op(op), _arg2(arg2) {}
  94. typename Op::ResultType operator()(typename Op::FirstArgumentType v) const {
  95. return _op(v, _arg2);
  96. }
  97. };
  98. /**
  99. * Transforms a binary function object into an unary function object.
  100. * To achieve that the first parameter is bound to the passed value t.
  101. */
  102. template<class Op>
  103. inline Binder2nd<Op> bind2nd(const Op &op, typename Op::SecondArgumentType t) {
  104. return Binder2nd<Op>(op, t);
  105. }
  106. template<class Arg, class Result>
  107. class PointerToUnaryFunc : public UnaryFunction<Arg, Result> {
  108. private:
  109. Result (*_func)(Arg);
  110. public:
  111. typedef Result (*FuncType)(Arg);
  112. PointerToUnaryFunc(const FuncType &func) : _func(func) {}
  113. Result operator()(Arg v) const {
  114. return _func(v);
  115. }
  116. };
  117. template<class Arg1, class Arg2, class Result>
  118. class PointerToBinaryFunc : public BinaryFunction<Arg1, Arg2, Result> {
  119. private:
  120. Result (*_func)(Arg1, Arg2);
  121. public:
  122. typedef Result (*FuncType)(Arg1, Arg2);
  123. PointerToBinaryFunc(const FuncType &func) : _func(func) {}
  124. Result operator()(Arg1 v1, Arg2 v2) const {
  125. return _func(v1, v2);
  126. }
  127. };
  128. /**
  129. * Creates an unary function object from a function pointer.
  130. */
  131. template<class Arg, class Result>
  132. inline PointerToUnaryFunc<Arg, Result> ptr_fun(Result (*func)(Arg)) {
  133. return PointerToUnaryFunc<Arg, Result>(func);
  134. }
  135. /**
  136. * Creates an binary function object from a function pointer.
  137. */
  138. template<class Arg1, class Arg2, class Result>
  139. inline PointerToBinaryFunc<Arg1, Arg2, Result> ptr_fun(Result (*func)(Arg1, Arg2)) {
  140. return PointerToBinaryFunc<Arg1, Arg2, Result>(func);
  141. }
  142. template<class Result, class T>
  143. class MemFunc0 : public UnaryFunction<T *, Result> {
  144. private:
  145. Result (T::*_func)();
  146. public:
  147. typedef Result (T::*FuncType)();
  148. MemFunc0(const FuncType &func) : _func(func) {}
  149. Result operator()(T *v) const {
  150. return (v->*_func)();
  151. }
  152. };
  153. template<class Result, class T>
  154. class ConstMemFunc0 : public UnaryFunction<T *, Result> {
  155. private:
  156. Result (T::*_func)() const;
  157. public:
  158. typedef Result (T::*FuncType)() const;
  159. ConstMemFunc0(const FuncType &func) : _func(func) {}
  160. Result operator()(const T *v) const {
  161. return (v->*_func)();
  162. }
  163. };
  164. template<class Result, class Arg, class T>
  165. class MemFunc1 : public BinaryFunction<T *, Arg, Result> {
  166. private:
  167. Result (T::*_func)(Arg);
  168. public:
  169. typedef Result (T::*FuncType)(Arg);
  170. MemFunc1(const FuncType &func) : _func(func) {}
  171. Result operator()(T *v1, Arg v2) const {
  172. return (v1->*_func)(v2);
  173. }
  174. };
  175. template<class Result, class Arg, class T>
  176. class ConstMemFunc1 : public BinaryFunction<T *, Arg, Result> {
  177. private:
  178. Result (T::*_func)(Arg) const;
  179. public:
  180. typedef Result (T::*FuncType)(Arg) const;
  181. ConstMemFunc1(const FuncType &func) : _func(func) {}
  182. Result operator()(const T *v1, Arg v2) const {
  183. return (v1->*_func)(v2);
  184. }
  185. };
  186. /**
  187. * Creates a unary function object from a class member function pointer.
  188. * The parameter passed to the function object is the 'this' pointer to
  189. * be used for the function call.
  190. */
  191. template<class Result, class T>
  192. inline MemFunc0<Result, T> mem_fun(Result (T::*f)()) {
  193. return MemFunc0<Result, T>(f);
  194. }
  195. /**
  196. * Creates a unary function object from a class member function pointer.
  197. * The parameter passed to the function object is the 'this' pointer to
  198. * be used for the function call.
  199. */
  200. template<class Result, class T>
  201. inline ConstMemFunc0<Result, T> mem_fun(Result (T::*f)() const) {
  202. return ConstMemFunc0<Result, T>(f);
  203. }
  204. /**
  205. * Creates a binary function object from a class member function pointer.
  206. * The first parameter passed to the function object is the 'this' pointer to
  207. * be used for the function call.
  208. * The second one is the parameter passed to the member function.
  209. */
  210. template<class Result, class Arg, class T>
  211. inline MemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg)) {
  212. return MemFunc1<Result, Arg, T>(f);
  213. }
  214. /**
  215. * Creates a binary function object from a class member function pointer.
  216. * The first parameter passed to the function object is the 'this' pointer to
  217. * be used for the function call.
  218. * The second one is the parameter passed to the member function.
  219. */
  220. template<class Result, class Arg, class T>
  221. inline ConstMemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg) const) {
  222. return ConstMemFunc1<Result, Arg, T>(f);
  223. }
  224. template<class Result, class T>
  225. class MemFuncRef0 : public UnaryFunction<T &, Result> {
  226. private:
  227. Result (T::*_func)();
  228. public:
  229. typedef Result (T::*FuncType)();
  230. MemFuncRef0(const FuncType &func) : _func(func) {}
  231. Result operator()(T &v) const {
  232. return (v.*_func)();
  233. }
  234. };
  235. template<class Result, class T>
  236. class ConstMemFuncRef0 : public UnaryFunction<T &, Result> {
  237. private:
  238. Result (T::*_func)() const;
  239. public:
  240. typedef Result (T::*FuncType)() const;
  241. ConstMemFuncRef0(const FuncType &func) : _func(func) {}
  242. Result operator()(const T &v) const {
  243. return (v.*_func)();
  244. }
  245. };
  246. template<class Result, class Arg, class T>
  247. class MemFuncRef1 : public BinaryFunction<T &, Arg, Result> {
  248. private:
  249. Result (T::*_func)(Arg);
  250. public:
  251. typedef Result (T::*FuncType)(Arg);
  252. MemFuncRef1(const FuncType &func) : _func(func) {}
  253. Result operator()(T &v1, Arg v2) const {
  254. return (v1.*_func)(v2);
  255. }
  256. };
  257. template<class Result, class Arg, class T>
  258. class ConstMemFuncRef1 : public BinaryFunction<T &, Arg, Result> {
  259. private:
  260. Result (T::*_func)(Arg) const;
  261. public:
  262. typedef Result (T::*FuncType)(Arg) const;
  263. ConstMemFuncRef1(const FuncType &func) : _func(func) {}
  264. Result operator()(const T &v1, Arg v2) const {
  265. return (v1.*_func)(v2);
  266. }
  267. };
  268. /**
  269. * Creates a unary function object from a class member function pointer.
  270. * The parameter passed to the function object is the object instance to
  271. * be used for the function call. Note unlike mem_fun, it takes a reference
  272. * as parameter. Note unlike mem_fun, it takes a reference
  273. * as parameter.
  274. */
  275. template<class Result, class T>
  276. inline MemFuncRef0<Result, T> mem_fun_ref(Result (T::*f)()) {
  277. return MemFuncRef0<Result, T>(f);
  278. }
  279. /**
  280. * Creates a unary function object from a class member function pointer.
  281. * The parameter passed to the function object is the object instance to
  282. * be used for the function call. Note unlike mem_fun, it takes a reference
  283. * as parameter.
  284. */
  285. template<class Result, class T>
  286. inline ConstMemFuncRef0<Result, T> mem_fun_Ref(Result (T::*f)() const) {
  287. return ConstMemFuncRef0<Result, T>(f);
  288. }
  289. /**
  290. * Creates a binary function object from a class member function pointer.
  291. * The first parameter passed to the function object is the object instance to
  292. * be used for the function call. Note unlike mem_fun, it takes a reference
  293. * as parameter.
  294. * The second one is the parameter passed to the member function.
  295. */
  296. template<class Result, class Arg, class T>
  297. inline MemFuncRef1<Result, Arg, T> mem_fun_ref(Result (T::*f)(Arg)) {
  298. return MemFuncRef1<Result, Arg, T>(f);
  299. }
  300. /**
  301. * Creates a binary function object from a class member function pointer.
  302. * The first parameter passed to the function object is the object instance to
  303. * be used for the function call. Note unlike mem_fun, it takes a reference
  304. * as parameter.
  305. * The second one is the parameter passed to the member function.
  306. */
  307. template<class Result, class Arg, class T>
  308. inline ConstMemFuncRef1<Result, Arg, T> mem_fun_ref(Result (T::*f)(Arg) const) {
  309. return ConstMemFuncRef1<Result, Arg, T>(f);
  310. }
  311. // functor code
  312. /**
  313. * Generic functor object for function objects without parameters.
  314. *
  315. * @see Functor1
  316. */
  317. template<class Res>
  318. struct Functor0 {
  319. virtual ~Functor0() {}
  320. virtual bool isValid() const = 0;
  321. virtual Res operator()() const = 0;
  322. };
  323. /**
  324. * Functor object for a class member function without parameter.
  325. *
  326. * Example creation:
  327. *
  328. * Foo bar;
  329. * Functor0Mem<void, Foo> myFunctor(&bar, &Foo::myFunc);
  330. *
  331. * Example usage:
  332. *
  333. * myFunctor();
  334. */
  335. template<class Res, class T>
  336. class Functor0Mem : public Functor0<Res> {
  337. public:
  338. typedef Res (T::*FuncType)();
  339. Functor0Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
  340. bool isValid() const { return _func != 0 && _t != 0; }
  341. Res operator()() const {
  342. return (_t->*_func)();
  343. }
  344. private:
  345. mutable T *_t;
  346. const FuncType _func;
  347. };
  348. /**
  349. * Generic functor object for unary function objects.
  350. *
  351. * A typical usage for an unary function object is for executing opcodes
  352. * in a script interpreter. To achieve that one can create an Common::Array
  353. * object with 'Functor1<Arg, Res> *' as type. Now after the right engine version
  354. * has been determined and the opcode table to use is found one could easily
  355. * add the opcode implementations like this:
  356. *
  357. * Common::Array<Functor1<ScriptState, void> *> opcodeTable;
  358. * opcodeTable[0] = new Functor1Mem<ScriptState, void, MyEngine_v1>(&myEngine, &MyEngine_v1::o1_foo);
  359. * opcodeTable[1] = new Functor1Mem<ScriptState, void, MyEngine_v2>(&myEngine, &MyEngine_v2::o2_foo);
  360. * // unimplemented/unused opcode
  361. * opcodeTable[2] = 0;
  362. * etc.
  363. *
  364. * This makes it easy to add member functions of different classes as
  365. * opcode functions to the function table. Since with the generic
  366. * Functor1<ScriptState, void> object the only requirement for an
  367. * function to be used is 'ScriptState' as argument and 'void' as return
  368. * value.
  369. *
  370. * Now for calling the opcodes one has simple to do:
  371. * if (opcodeTable[opcodeNum] && opcodeTable[opcodeNum]->isValid())
  372. * (*opcodeTable[opcodeNum])(scriptState);
  373. * else
  374. * warning("Unimplemented opcode %d", opcodeNum);
  375. *
  376. * If you want to see an real world example check the kyra engine.
  377. * Files: engines/kyra/script.cpp and .h and engines/kyra/script_*.cpp
  378. * are interesting for that matter.
  379. */
  380. template<class Arg, class Res>
  381. struct Functor1 : public Common::UnaryFunction<Arg, Res> {
  382. virtual ~Functor1() {}
  383. virtual bool isValid() const = 0;
  384. virtual Res operator()(Arg) const = 0;
  385. };
  386. /**
  387. * Functor object for an unary class member function.
  388. * Usage is like with Functor0Mem. The resulting functor object
  389. * will take one parameter though.
  390. *
  391. * @see Functor0Mem
  392. */
  393. template<class Arg, class Res, class T>
  394. class Functor1Mem : public Functor1<Arg, Res> {
  395. public:
  396. typedef Res (T::*FuncType)(Arg);
  397. Functor1Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
  398. bool isValid() const { return _func != 0 && _t != 0; }
  399. Res operator()(Arg v1) const {
  400. return (_t->*_func)(v1);
  401. }
  402. private:
  403. mutable T *_t;
  404. const FuncType _func;
  405. };
  406. /**
  407. * Generic functor object for binary function objects.
  408. *
  409. * @see Functor1
  410. */
  411. template<class Arg1, class Arg2, class Res>
  412. struct Functor2 : public Common::BinaryFunction<Arg1, Arg2, Res> {
  413. virtual ~Functor2() {}
  414. virtual bool isValid() const = 0;
  415. virtual Res operator()(Arg1, Arg2) const = 0;
  416. };
  417. /**
  418. * Functor object for a binary function.
  419. *
  420. * @see Functor2Mem
  421. */
  422. template<class Arg1, class Arg2, class Res>
  423. class Functor2Fun : public Functor2<Arg1, Arg2, Res> {
  424. public:
  425. typedef Res (*FuncType)(Arg1, Arg2);
  426. Functor2Fun(const FuncType func) : _func(func) {}
  427. bool isValid() const { return _func != 0; }
  428. Res operator()(Arg1 v1, Arg2 v2) const {
  429. return (*_func)(v1, v2);
  430. }
  431. private:
  432. const FuncType _func;
  433. };
  434. /**
  435. * Functor object for a binary class member function.
  436. * Usage is like with Functor0Mem. The resulting functor object
  437. * will take two parameter though.
  438. *
  439. * @see Functor0Mem
  440. */
  441. template<class Arg1, class Arg2, class Res, class T>
  442. class Functor2Mem : public Functor2<Arg1, Arg2, Res> {
  443. public:
  444. typedef Res (T::*FuncType)(Arg1, Arg2);
  445. Functor2Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
  446. bool isValid() const { return _func != 0 && _t != 0; }
  447. Res operator()(Arg1 v1, Arg2 v2) const {
  448. return (_t->*_func)(v1, v2);
  449. }
  450. private:
  451. mutable T *_t;
  452. const FuncType _func;
  453. };
  454. /**
  455. * Base template for hash functor objects, used by HashMap.
  456. * This needs to be specialized for every type that you need to hash.
  457. */
  458. template<typename T> struct Hash;
  459. #define GENERATE_TRIVIAL_HASH_FUNCTOR(T) \
  460. template<> struct Hash<T> : public UnaryFunction<T, uint> { \
  461. uint operator()(T val) const { return (uint)val; } \
  462. }
  463. GENERATE_TRIVIAL_HASH_FUNCTOR(bool);
  464. GENERATE_TRIVIAL_HASH_FUNCTOR(char);
  465. GENERATE_TRIVIAL_HASH_FUNCTOR(signed char);
  466. GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned char);
  467. GENERATE_TRIVIAL_HASH_FUNCTOR(short);
  468. GENERATE_TRIVIAL_HASH_FUNCTOR(int);
  469. GENERATE_TRIVIAL_HASH_FUNCTOR(long);
  470. GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned short);
  471. GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned int);
  472. GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned long);
  473. #undef GENERATE_TRIVIAL_HASH_FUNCTOR
  474. } // End of namespace Common
  475. #endif