1/**
2 * @file   rubystdfunctors.swg
3 * @date   Sun May  6 00:44:33 2007
4 *
5 * @brief  This file provides unary and binary functors for STL
6 *         containers, that will invoke a Ruby proc or method to do
7 *         their operation.
8 *
9 *         You can use them in a swig file like:
10 *
11 *         %include <std_set.i>
12 *         %include <std_functors.i>
13 *
14 *         %template< IntSet > std::set< int, swig::BinaryPredicate<> >;
15 *
16 *
17 *         which will then allow calling them from Ruby either like:
18 *
19 *            # order of set is defined by C++ default
20 *            a = IntSet.new
21 *
22 *            # sort order defined by Ruby proc
23 *            b = IntSet.new( proc { |a,b| a > b } )
24 *
25 */
26
27%include rubyclasses.swg
28
29
30namespace swig {
31
32  %apply GC_VALUE { UnaryPredicate, BinaryPredicate, UnaryFunction,
33		      BinaryFunction };
34
35  %typecheck(SWIG_TYPECHECK_POINTER,noblock=1)
36    UnaryPredicate, UnaryPredicate&, UnaryFunction, UnaryFunction&
37  {
38    $1 = SWIG_Ruby_isCallable($input) && SWIG_Ruby_arity($input, 1);
39  }
40
41  %typecheck(SWIG_TYPECHECK_POINTER,noblock=1)
42    BinaryPredicate, BinaryPredicate&, BinaryFunction, BinaryFunction& {
43    $1 = SWIG_Ruby_isCallable($input) && SWIG_Ruby_arity($input, 2);
44  }
45
46  %typemap(in,noblock=1)  BinaryFunction&, BinaryFunction {
47    $1 = new swig::BinaryFunction< >($input);
48  }
49  %typemap(in,noblock=1) UnaryFunction&, UnaryFunction {
50    $1 = new swig::UnaryFunction< >($input);
51  }
52
53  %typemap(in,noblock=1) BinaryPredicate&, BinaryPredicate {
54    $1 = new swig::BinaryPredicate<>($input);
55  }
56
57  %typemap(in,noblock=1) UnaryPredicate&, UnaryPredicate {
58    $1 = new swig::UnaryPredicate< >($input);
59  }
60
61
62  %ignore BinaryFunction;
63  template< class _T = GC_VALUE >
64  struct BinaryFunction {
65  };
66
67  %ignore UnaryFunction;
68  template< class _T = GC_VALUE >
69  struct UnaryFunction {
70  };
71
72  %ignore BinaryPredicate;
73  template< class _T = GC_VALUE >
74  struct BinaryPredicate {
75  };
76
77  %ignore UnaryPredicate;
78  template< class _T = GC_VALUE >
79  struct UnaryPredicate {
80
81  };
82
83}
84
85
86%fragment("StdFunctors","header",fragment="StdTraits")
87{
88namespace swig {
89
90  static ID call_id = rb_intern("call");
91
92  template <class _T = GC_VALUE, class _DefaultFunc = std::less<GC_VALUE> >
93  struct BinaryPredicate : GC_VALUE, std::binary_function< _T, _T, bool >
94  {
95    BinaryPredicate(VALUE obj = Qnil) : GC_VALUE(obj) { }
96    bool operator()(_T a, _T b) const
97    {
98      if (_obj != Qnil) {
99        SWIG_RUBY_THREAD_BEGIN_BLOCK;
100	VALUE arg1 = swig::from(a);
101	VALUE arg2 = swig::from(b);
102	VALUE res = rb_funcall( _obj, swig::call_id, 2, arg1, arg2);
103        SWIG_RUBY_THREAD_END_BLOCK;
104        return RTEST(res);
105      } else {
106        return _DefaultFunc()(a, b);
107      }
108    }
109  };
110
111  template <class _T = GC_VALUE, class _DefaultFunc = std::less< _T > >
112  struct BinaryFunction : GC_VALUE, std::binary_function< _T, _T, _T >
113  {
114    BinaryFunction(VALUE obj = Qnil) : GC_VALUE(obj) { }
115    _T operator()(_T a, _T b) const
116    {
117      if (_obj != Qnil) {
118        SWIG_RUBY_THREAD_BEGIN_BLOCK;
119	VALUE arg1 = swig::from(a);
120	VALUE arg2 = swig::from(b);
121	VALUE res = rb_funcall( _obj, swig::call_id, 2, arg1, arg2);
122        SWIG_RUBY_THREAD_END_BLOCK;
123        return swig::as<_T >(res);
124      } else {
125        return _DefaultFunc()(a, b);
126      }
127    }
128  };
129
130  template< class _T = GC_VALUE >
131  struct UnaryPredicate : GC_VALUE, std::unary_function< _T, bool >
132  {
133    UnaryPredicate(VALUE obj = Qnil) : GC_VALUE(obj) { }
134    bool operator()(_T a) const
135    {
136      SWIG_RUBY_THREAD_BEGIN_BLOCK;
137      VALUE arg1 = swig::from<_T >(a);
138      VALUE res = rb_funcall( _obj, swig::call_id, 1, arg1);
139      SWIG_RUBY_THREAD_END_BLOCK;
140      return RTEST(res);
141    }
142  };
143
144  template< class _T = GC_VALUE >
145  struct UnaryFunction : GC_VALUE, std::unary_function< _T, _T >
146  {
147    UnaryFunction(VALUE obj = Qnil) : GC_VALUE(obj) { }
148    _T operator()(_T a) const
149    {
150      SWIG_RUBY_THREAD_BEGIN_BLOCK;
151      VALUE arg1 = swig::from(a);
152      VALUE res = rb_funcall( _obj, swig::call_id, 1, VALUE(arg1));
153      SWIG_RUBY_THREAD_END_BLOCK;
154      return swig::as< _T >(res);
155    }
156  };
157
158} // namespace swig
159
160}
161
162
163