Ticket #1267: functional.h

File functional.h, 15.4 KB (added by anonymous, 18 months ago)
Line 
1// rak - Rakshasa's toolbox
2// Copyright (C) 2005-2007, Jari Sundell
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17//
18// In addition, as a special exception, the copyright holders give
19// permission to link the code of portions of this program with the
20// OpenSSL library under certain conditions as described in each
21// individual source file, and distribute linked combinations
22// including the two.
23//
24// You must obey the GNU General Public License in all respects for
25// all of the code used other than OpenSSL.  If you modify file(s)
26// with this exception, you may extend this exception to your version
27// of the file(s), but you are not obligated to do so.  If you do not
28// wish to do so, delete this exception statement from your version.
29// If you delete this exception statement from all source files in the
30// program, then also delete it here.
31//
32// Contact:  Jari Sundell <jaris@ifi.uio.no>
33//
34//           Skomakerveien 33
35//           3185 Skoppum, NORWAY
36
37#ifndef RAK_FUNCTIONAL_H
38#define RAK_FUNCTIONAL_H
39
40#include <functional>
41
42namespace rak {
43
44template <typename Type>
45struct reference_fix {
46  typedef Type type;
47};
48
49template <typename Type>
50struct reference_fix<Type&> {
51  typedef Type type;
52};
53
54template <typename Type>
55struct value_t {
56  value_t(Type v) : m_v(v) {}
57
58  Type operator () () const { return m_v; }
59
60  Type m_v;
61};
62
63template <typename Type>
64inline value_t<Type>
65value(Type v) {
66  return value_t<Type>(v);
67}
68
69template <typename Type, typename Ftor>
70struct accumulate_t {
71  accumulate_t(Type t, Ftor f) : result(t), m_f(f) {}
72
73  template <typename Arg>
74  void operator () (const Arg& a) { result += m_f(a); }
75
76  Type result;
77  Ftor m_f;
78};
79
80template <typename Type, typename Ftor>
81inline accumulate_t<Type, Ftor>
82accumulate(Type t, Ftor f) {
83  return accumulate_t<Type, Ftor>(t, f);
84}
85
86// Operators:
87
88template <typename Type, typename Ftor>
89struct equal_t {
90  typedef bool result_type;
91
92  equal_t(Type t, Ftor f) : m_t(t), m_f(f) {}
93
94  template <typename Arg>
95  bool operator () (Arg& a) {
96    return m_t == m_f(a);
97  }
98
99  Type m_t;
100  Ftor m_f;
101};
102
103template <typename Type, typename Ftor>
104inline equal_t<Type, Ftor>
105equal(Type t, Ftor f) {
106  return equal_t<Type, Ftor>(t, f);
107}
108
109template <typename Type, typename Ftor>
110struct equal_ptr_t {
111  typedef bool result_type;
112
113  equal_ptr_t(Type* t, Ftor f) : m_t(t), m_f(f) {}
114
115  template <typename Arg>
116  bool operator () (const Arg& a) {
117    return *m_t == *m_f(a);
118  }
119
120  Type* m_t;
121  Ftor  m_f;
122};
123
124template <typename Type, typename Ftor>
125inline equal_ptr_t<Type, Ftor>
126equal_ptr(Type* t, Ftor f) {
127  return equal_ptr_t<Type, Ftor>(t, f);
128}
129
130template <typename Type, typename Ftor>
131struct not_equal_t {
132  typedef bool result_type;
133
134  not_equal_t(Type t, Ftor f) : m_t(t), m_f(f) {}
135
136  template <typename Arg>
137  bool operator () (Arg& a) {
138    return m_t != m_f(a);
139  }
140
141  Type m_t;
142  Ftor m_f;
143};
144
145template <typename Type, typename Ftor>
146inline not_equal_t<Type, Ftor>
147not_equal(Type t, Ftor f) {
148  return not_equal_t<Type, Ftor>(t, f);
149}
150
151template <typename Type, typename Ftor>
152struct less_t {
153  typedef bool result_type;
154
155  less_t(Type t, Ftor f) : m_t(t), m_f(f) {}
156
157  template <typename Arg>
158  bool operator () (Arg& a) {
159    return m_t < m_f(a);
160  }
161
162  Type m_t;
163  Ftor m_f;
164};
165
166template <typename Type, typename Ftor>
167inline less_t<Type, Ftor>
168less(Type t, Ftor f) {
169  return less_t<Type, Ftor>(t, f);
170}
171
172template <typename FtorA, typename FtorB>
173struct less2_t : public std::binary_function<typename FtorA::argument_type, typename FtorB::argument_type, bool> {
174  less2_t(FtorA f_a, FtorB f_b) : m_f_a(f_a), m_f_b(f_b) {}
175
176  bool operator () (typename FtorA::argument_type a, typename FtorB::argument_type b) {
177    return m_f_a(a) < m_f_b(b);
178  }
179
180  FtorA m_f_a;
181  FtorB m_f_b;
182};
183
184template <typename FtorA, typename FtorB>
185inline less2_t<FtorA, FtorB>
186less2(FtorA f_a, FtorB f_b) {
187  return less2_t<FtorA,FtorB>(f_a,f_b);
188}
189
190template <typename Type, typename Ftor>
191struct _greater {
192  typedef bool result_type;
193
194  _greater(Type t, Ftor f) : m_t(t), m_f(f) {}
195
196  template <typename Arg>
197  bool operator () (Arg& a) {
198    return m_t > m_f(a);
199  }
200
201  Type m_t;
202  Ftor m_f;
203};
204
205template <typename Type, typename Ftor>
206inline _greater<Type, Ftor>
207greater(Type t, Ftor f) {
208  return _greater<Type, Ftor>(t, f);
209}
210
211template <typename FtorA, typename FtorB>
212struct greater2_t : public std::binary_function<typename FtorA::argument_type, typename FtorB::argument_type, bool> {
213  greater2_t(FtorA f_a, FtorB f_b) : m_f_a(f_a), m_f_b(f_b) {}
214
215  bool operator () (typename FtorA::argument_type a, typename FtorB::argument_type b) {
216    return m_f_a(a) > m_f_b(b);
217  }
218
219  FtorA m_f_a;
220  FtorB m_f_b;
221};
222
223template <typename FtorA, typename FtorB>
224inline greater2_t<FtorA, FtorB>
225greater2(FtorA f_a, FtorB f_b) {
226  return greater2_t<FtorA,FtorB>(f_a,f_b);
227}
228
229template <typename Type, typename Ftor>
230struct less_equal_t {
231  typedef bool result_type;
232
233  less_equal_t(Type t, Ftor f) : m_t(t), m_f(f) {}
234
235  template <typename Arg>
236  bool operator () (Arg& a) {
237    return m_t <= m_f(a);
238  }
239
240  Type m_t;
241  Ftor m_f;
242};
243
244template <typename Type, typename Ftor>
245inline less_equal_t<Type, Ftor>
246less_equal(Type t, Ftor f) {
247  return less_equal_t<Type, Ftor>(t, f);
248}
249
250template <typename Type, typename Ftor>
251struct greater_equal_t {
252  typedef bool result_type;
253
254  greater_equal_t(Type t, Ftor f) : m_t(t), m_f(f) {}
255
256  template <typename Arg>
257  bool operator () (Arg& a) {
258    return m_t >= m_f(a);
259  }
260
261  Type m_t;
262  Ftor m_f;
263};
264
265template <typename Type, typename Ftor>
266inline greater_equal_t<Type, Ftor>
267greater_equal(Type t, Ftor f) {
268  return greater_equal_t<Type, Ftor>(t, f);
269}
270
271template<typename Tp>
272struct invert : public std::unary_function<Tp, Tp> {
273  Tp
274  operator () (const Tp& x) const { return ~x; }
275};
276
277template <typename Src, typename Dest>
278struct on_t : public std::unary_function<typename Src::argument_type, typename Dest::result_type> {
279  typedef typename Dest::result_type result_type;
280
281  on_t(Src s, Dest d) : m_dest(d), m_src(s) {}
282
283  result_type operator () (typename reference_fix<typename Src::argument_type>::type arg) {
284    return m_dest(m_src(arg));
285  }
286
287  Dest m_dest;
288  Src m_src;
289};
290   
291template <typename Src, typename Dest>
292inline on_t<Src, Dest>
293on(Src s, Dest d) {
294  return on_t<Src, Dest>(s, d);
295} 
296
297template <typename Src, typename Dest>
298struct on2_t : public std::binary_function<typename Src::argument_type, typename Dest::second_argument_type, typename Dest::result_type> {
299  typedef typename Dest::result_type result_type;
300
301  on2_t(Src s, Dest d) : m_dest(d), m_src(s) {}
302
303  result_type operator () (typename reference_fix<typename Src::argument_type>::type first, typename reference_fix<typename Dest::second_argument_type>::type second) {
304    return m_dest(m_src(first), second);
305  }
306
307  Dest m_dest;
308  Src m_src;
309};
310   
311template <typename Src, typename Dest>
312inline on2_t<Src, Dest>
313on2(Src s, Dest d) {
314  return on2_t<Src, Dest>(s, d);
315} 
316
317// Creates a functor for accessing a member.
318template <typename Class, typename Member>
319struct mem_ptr_t : public std::unary_function<Class*, Member&> {
320  mem_ptr_t(Member Class::*m) : m_member(m) {}
321
322  Member& operator () (Class* c) {
323    return c->*m_member;
324  }
325
326  const Member& operator () (const Class* c) {
327    return c->*m_member;
328  }
329
330  Member Class::*m_member;
331};
332
333template <typename Class, typename Member>
334inline mem_ptr_t<Class, Member>
335mem_ptr(Member Class::*m) {
336  return mem_ptr_t<Class, Member>(m);
337}
338
339template <typename Class, typename Member>
340struct mem_ref_t : public std::unary_function<Class&, Member&> {
341  mem_ref_t(Member Class::*m) : m_member(m) {}
342
343  Member& operator () (Class& c) {
344    return c.*m_member;
345  }
346
347  Member Class::*m_member;
348};
349
350template <typename Class, typename Member>
351struct const_mem_ref_t : public std::unary_function<const Class&, const Member&> {
352  const_mem_ref_t(const Member Class::*m) : m_member(m) {}
353
354  const Member& operator () (const Class& c) {
355    return c.*m_member;
356  }
357
358  const Member Class::*m_member;
359};
360
361template <typename Class, typename Member>
362inline mem_ref_t<Class, Member>
363mem_ref(Member Class::*m) {
364  return mem_ref_t<Class, Member>(m);
365}
366
367template <typename Class, typename Member>
368inline const_mem_ref_t<Class, Member>
369const_mem_ref(const Member Class::*m) {
370  return const_mem_ref_t<Class, Member>(m);
371}
372
373template <typename Cond, typename Then>
374struct if_then_t {
375  if_then_t(Cond c, Then t) : m_cond(c), m_then(t) {}
376
377  template <typename Arg>
378  void operator () (Arg& a) {
379    if (m_cond(a))
380      m_then(a);
381  }
382
383  Cond m_cond;
384  Then m_then;
385};
386
387template <typename Cond, typename Then>
388inline if_then_t<Cond, Then>
389if_then(Cond c, Then t) {
390  return if_then_t<Cond, Then>(c, t);
391}
392
393template <typename T>
394struct call_delete : public std::unary_function<T*, void> {
395  void operator () (T* t) {
396    delete t;
397  }
398};
399
400template <typename T>
401inline void
402call_delete_func(T* t) {
403  delete t;
404}
405
406template <typename Operation>
407class bind1st_t : public std::unary_function<typename Operation::second_argument_type, typename Operation::result_type> {
408public:
409  typedef typename reference_fix<typename Operation::first_argument_type>::type  value_type;
410  typedef typename reference_fix<typename Operation::second_argument_type>::type argument_type;
411
412  bind1st_t(const Operation& op, const value_type v) :
413    m_op(op), m_value(v) {}
414
415  typename Operation::result_type
416  operator () (const argument_type arg) {
417    return m_op(m_value, arg);
418  }
419
420protected:
421  Operation  m_op;
422  value_type m_value;
423};
424
425template <typename Operation, typename Type>
426inline bind1st_t<Operation>
427bind1st(const Operation& op, const Type& val) {
428  return bind1st_t<Operation>(op, val);
429}
430
431template <typename Operation>
432class bind2nd_t : public std::unary_function<typename Operation::first_argument_type, typename Operation::result_type> {
433public:
434  typedef typename reference_fix<typename Operation::first_argument_type>::type argument_type;
435  typedef typename reference_fix<typename Operation::second_argument_type>::type value_type;
436
437  bind2nd_t(const Operation& op, const value_type v) :
438    m_op(op), m_value(v) {}
439
440  typename Operation::result_type
441  operator () (argument_type arg) {
442    return m_op(arg, m_value);
443  }
444
445protected:
446  Operation  m_op;
447  value_type m_value;
448};
449
450template <typename Operation, typename Type>
451inline bind2nd_t<Operation>
452bind2nd(const Operation& op, const Type& val) {
453  return bind2nd_t<Operation>(op, val);
454}
455
456// Lightweight callback function including pointer to object. Should
457// be replaced by TR1 stuff later. Requires an object to bind, instead
458// of using a seperate functor for that.
459
460template <typename Ret>
461class ptr_fun0 {
462public:
463  typedef Ret result_type;
464  typedef Ret (*Function)();
465
466  ptr_fun0() {}
467  ptr_fun0(Function f) : m_function(f) {}
468
469  bool is_valid() const { return m_function; }
470
471  Ret operator () () { return m_function(); }
472 
473private:
474  Function m_function;
475};
476
477template <typename Object, typename Ret>
478class mem_fun0 {
479public:
480  typedef Ret result_type;
481  typedef Ret (Object::*Function)();
482
483  mem_fun0() : m_object(NULL) {}
484  mem_fun0(Object* o, Function f) : m_object(o), m_function(f) {}
485
486  bool is_valid() const { return m_object; }
487
488  Ret operator () () { return (m_object->*m_function)(); }
489 
490private:
491  Object* m_object;
492  Function m_function;
493};
494
495template <typename Object, typename Ret>
496class const_mem_fun0 {
497public:
498  typedef Ret result_type;
499  typedef Ret (Object::*Function)() const;
500
501  const_mem_fun0() : m_object(NULL) {}
502  const_mem_fun0(const Object* o, Function f) : m_object(o), m_function(f) {}
503
504  bool is_valid() const { return m_object; }
505
506  Ret operator () () const { return (m_object->*m_function)(); }
507 
508private:
509  const Object* m_object;
510  Function      m_function;
511};
512
513template <typename Object, typename Ret, typename Arg1>
514class mem_fun1 {
515public:
516  typedef Ret result_type;
517  typedef Ret (Object::*Function)(Arg1);
518
519  mem_fun1() : m_object(NULL) {}
520  mem_fun1(Object* o, Function f) : m_object(o), m_function(f) {}
521
522  bool is_valid() const { return m_object; }
523
524  Ret operator () (Arg1 a1) { return (m_object->*m_function)(a1); }
525 
526private:
527  Object* m_object;
528  Function m_function;
529};
530
531template <typename Object, typename Ret, typename Arg1>
532class const_mem_fun1 {
533public:
534  typedef Ret result_type;
535  typedef Ret (Object::*Function)(Arg1) const;
536
537  const_mem_fun1() : m_object(NULL) {}
538  const_mem_fun1(const Object* o, Function f) : m_object(o), m_function(f) {}
539
540  bool is_valid() const { return m_object; }
541
542  Ret operator () (Arg1 a1) const { return (m_object->*m_function)(a1); }
543 
544private:
545  const Object* m_object;
546  Function      m_function;
547};
548
549template <typename Object, typename Ret, typename Arg1, typename Arg2>
550class mem_fun2 : public std::binary_function<Arg1, Arg2, Ret> {
551public:
552  typedef Ret result_type;
553  typedef Ret (Object::*Function)(Arg1, Arg2);
554  typedef Object object_type;
555
556  mem_fun2() : m_object(NULL) {}
557  mem_fun2(Object* o, Function f) : m_object(o), m_function(f) {}
558
559  bool         is_valid() const { return m_object; }
560
561  object_type*       object() { return m_object; }
562  const object_type* object() const { return m_object; }
563
564  Ret          operator () (Arg1 a1, Arg2 a2) { return (m_object->*m_function)(a1, a2); }
565 
566private:
567  Object* m_object;
568  Function m_function;
569};
570
571template <typename Object, typename Ret, typename Arg1, typename Arg2, typename Arg3>
572class mem_fun3 {
573public:
574  typedef Ret result_type;
575  typedef Ret (Object::*Function)(Arg1, Arg2, Arg3);
576
577  mem_fun3() : m_object(NULL) {}
578  mem_fun3(Object* o, Function f) : m_object(o), m_function(f) {}
579
580  bool is_valid() const { return m_object; }
581
582  Ret operator () (Arg1 a1, Arg2 a2, Arg3 a3) { return (m_object->*m_function)(a1, a2, a3); }
583 
584private:
585  Object* m_object;
586  Function m_function;
587};
588
589template <typename Ret>
590inline ptr_fun0<Ret>
591ptr_fun(Ret (*f)()) { return ptr_fun0<Ret>(f); }
592
593template <typename Object, typename Ret>
594inline mem_fun0<Object, Ret>
595make_mem_fun(Object* o, Ret (Object::*f)()) {
596 return mem_fun0<Object, Ret>(o, f);
597}
598
599template <typename Object, typename Ret>
600inline const_mem_fun0<Object, Ret>
601make_mem_fun(const Object* o, Ret (Object::*f)() const) {
602 return const_mem_fun0<Object, Ret>(o, f);
603}
604
605template <typename Object, typename Ret, typename Arg1>
606inline mem_fun1<Object, Ret, Arg1>
607make_mem_fun(Object* o, Ret (Object::*f)(Arg1)) {
608 return mem_fun1<Object, Ret, Arg1>(o, f);
609}
610
611template <typename Object, typename Ret, typename Arg1>
612inline const_mem_fun1<Object, Ret, Arg1>
613make_mem_fun(const Object* o, Ret (Object::*f)(Arg1) const) {
614 return const_mem_fun1<Object, Ret, Arg1>(o, f);
615}
616
617template <typename Object, typename Ret, typename Arg1, typename Arg2>
618inline mem_fun2<Object, Ret, Arg1, Arg2>
619make_mem_fun(Object* o, Ret (Object::*f)(Arg1, Arg2)) {
620 return mem_fun2<Object, Ret, Arg1, Arg2>(o, f);
621}
622
623template <typename Object, typename Ret, typename Arg1, typename Arg2, typename Arg3>
624inline mem_fun3<Object, Ret, Arg1, Arg2, Arg3>
625make_mem_fun(Object* o, Ret (Object::*f)(Arg1, Arg2, Arg3)) {
626 return mem_fun3<Object, Ret, Arg1, Arg2, Arg3>(o, f);
627}
628
629}
630
631#endif