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