| /** |
| * @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 |
| |
| } |
| |
| |