Added new rubycontainer_extended.swg file.
This file contains standard ruby algorithms but which place some restriction on the class inside the STL container. Fixed GC_VALUE so that it cannot be instantiated from the language manually. Fixed delete autodoc. Started documenting each portion of the SWIG templates/macros so it makes sense to people. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9773 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
c361c83aea
commit
1c46a18c50
6 changed files with 212 additions and 45 deletions
|
|
@ -59,7 +59,7 @@ AUTODOC(reject, "Iterate thru each element in the $class and reject those that f
|
||||||
AUTODOC(reject_bang, "Iterate thru each element in the $class and reject those that fail a condition. A block must be provided. $class is modified in place");
|
AUTODOC(reject_bang, "Iterate thru each element in the $class and reject those that fail a condition. A block must be provided. $class is modified in place");
|
||||||
AUTODOC(select, "Iterate thru each element in the $class and select those that match a condition. A block must be provided");
|
AUTODOC(select, "Iterate thru each element in the $class and select those that match a condition. A block must be provided");
|
||||||
AUTODOC(delete_at, "Delete an element at a certain index");
|
AUTODOC(delete_at, "Delete an element at a certain index");
|
||||||
AUTODOC(__delete__, "Delete an element at a certain index");
|
AUTODOC(__delete__, "Delete a matching element");
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
/*
|
/*
|
||||||
GC_VALUE is used as a replacement of VALUE.
|
GC_VALUE is used as a replacement of Ruby's VALUE.
|
||||||
GC_VALUE automatically handles registering and unregistering
|
GC_VALUE automatically handles registering and unregistering
|
||||||
of the underlying ruby object with the GC.
|
of the underlying ruby object with the GC.
|
||||||
|
|
||||||
|
|
@ -17,7 +17,8 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
or as a input/output value (not much use for this, thou):
|
or as a input/output value (not much use for this, as VALUE works as
|
||||||
|
well here, thou):
|
||||||
|
|
||||||
GC_VALUE func(GC_VALUE obj) {
|
GC_VALUE func(GC_VALUE obj) {
|
||||||
GC_VALUE out = rb_obj_classname(obj);
|
GC_VALUE out = rb_obj_classname(obj);
|
||||||
|
|
@ -34,11 +35,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace swig {
|
namespace swig {
|
||||||
// we don't ignore it, so it will get printed nicely with inspect
|
|
||||||
//%ignore GC_VALUE;
|
%nodirector GC_VALUE;
|
||||||
|
|
||||||
|
// We ignore the constructor so that user can never create a GC_VALUE manually
|
||||||
|
%ignore GC_VALUE::GC_VALUE;
|
||||||
|
|
||||||
struct GC_VALUE {
|
struct GC_VALUE {
|
||||||
VALUE inspect() const;
|
VALUE inspect() const;
|
||||||
VALUE to_s() const;
|
VALUE to_s() const;
|
||||||
|
GC_VALUE();
|
||||||
|
protected:
|
||||||
|
GC_VALUE( const GC_VALUE& );
|
||||||
|
~GC_VALUE();
|
||||||
};
|
};
|
||||||
|
|
||||||
%exception GC_VALUE {};
|
%exception GC_VALUE {};
|
||||||
|
|
@ -132,6 +141,12 @@ namespace swig {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* std::less< GC_VALUE > functor so that STL containers will accept
|
||||||
|
* GC_VALUE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
template <>
|
template <>
|
||||||
struct less< swig::GC_VALUE >: public binary_function< swig::GC_VALUE,
|
struct less< swig::GC_VALUE >: public binary_function< swig::GC_VALUE,
|
||||||
|
|
|
||||||
|
|
@ -579,23 +579,6 @@ namespace swig
|
||||||
%extend {
|
%extend {
|
||||||
|
|
||||||
|
|
||||||
// Implementing delete requires semantics that go beyond the
|
|
||||||
// default requirements of STD containers.
|
|
||||||
//
|
|
||||||
// VALUE __delete__( Sequence::value_type e ) {
|
|
||||||
// VALUE r = Qnil;
|
|
||||||
// std::size_t len = $self->size();
|
|
||||||
// std::remove_if( $self->begin(), $self->end(),
|
|
||||||
// std::bind2nd( std::equal_to< Sequence::value_type >(),
|
|
||||||
// e ) );
|
|
||||||
//
|
|
||||||
// if ( $self->size() != len )
|
|
||||||
// r = swig::from< Sequence::value_type >( e );
|
|
||||||
// else if ( rb_block_given_p() )
|
|
||||||
// r = rb_yield(Qnil);
|
|
||||||
// return r;
|
|
||||||
// }
|
|
||||||
|
|
||||||
VALUE slice( difference_type i, difference_type j )
|
VALUE slice( difference_type i, difference_type j )
|
||||||
{
|
{
|
||||||
if ( j <= 0 ) return Qnil;
|
if ( j <= 0 ) return Qnil;
|
||||||
|
|
@ -681,6 +664,12 @@ namespace swig
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VALUE __delete2__(const value_type& i) {
|
||||||
|
VALUE r = Qnil;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
%enddef
|
%enddef
|
||||||
|
|
||||||
|
|
@ -1033,3 +1022,6 @@ namespace swig {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
%include <rubycontainer_extended.swg>
|
||||||
|
|
|
||||||
140
Lib/ruby/rubycontainer_extended.swg
Normal file
140
Lib/ruby/rubycontainer_extended.swg
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
/**
|
||||||
|
* @file rubycontainer_extended.swg
|
||||||
|
* @author gga
|
||||||
|
* @date Sat May 5 05:36:01 2007
|
||||||
|
*
|
||||||
|
* @brief This file contains additional functions that make containers
|
||||||
|
* behave closer to ruby primitive types.
|
||||||
|
* However, some of these functions place some restrictions on
|
||||||
|
* the underlying object inside of the container (that it has
|
||||||
|
* an == comparison function, that it has an = assignment
|
||||||
|
* operator, etc).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macro used to add extend functions that require operator== in object.
|
||||||
|
*
|
||||||
|
* @param Container STL container
|
||||||
|
* @param Type class inside container
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
%define %swig_container_with_equal_operator( Container, Type )
|
||||||
|
|
||||||
|
VALUE __delete__( const Type& val ) {
|
||||||
|
VALUE r = Qnil;
|
||||||
|
Container<Type >::iterator e = $self->end();
|
||||||
|
Container<Type >::iterator i = std::remove( $self->begin(), e, val );
|
||||||
|
// remove dangling elements now
|
||||||
|
$self->erase( i, e );
|
||||||
|
|
||||||
|
if ( i != e )
|
||||||
|
r = swig::from< Type >( val );
|
||||||
|
else if ( rb_block_given_p() )
|
||||||
|
r = rb_yield(Qnil);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
%enddef // end of %swig_container_with_equal_operator
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macro used to add extend functions that require the assignment
|
||||||
|
* operator (ie. = ) of contained class
|
||||||
|
*
|
||||||
|
* @param Container STL container
|
||||||
|
* @param Type class inside container
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
%define %swig_container_with_assignment( Container, Type )
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// map!
|
||||||
|
//
|
||||||
|
Container< Type >* map_bang() {
|
||||||
|
|
||||||
|
if ( !rb_block_given_p() )
|
||||||
|
rb_raise( rb_eArgError, "No block given" );
|
||||||
|
|
||||||
|
VALUE r = Qnil;
|
||||||
|
Container< Type >::iterator i = $self->begin();
|
||||||
|
Container< Type >::iterator e = $self->end();
|
||||||
|
|
||||||
|
try {
|
||||||
|
for ( ; i != e; ++i )
|
||||||
|
{
|
||||||
|
r = swig::from< Type >( *i );
|
||||||
|
r = rb_yield( r );
|
||||||
|
*i = swig::as< Type >( r );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( const std::invalid_argument& )
|
||||||
|
{
|
||||||
|
rb_raise(rb_eTypeError,
|
||||||
|
"Yield block did not return a valid element for " #Container);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
%enddef // end of %swig_container_with_assignment
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macro used to add all extended functions to a container
|
||||||
|
*
|
||||||
|
* @param Container STL container
|
||||||
|
* @param Type class inside container
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
%define %swig_container_extend( Container, Type )
|
||||||
|
|
||||||
|
%extend Container< Type > {
|
||||||
|
|
||||||
|
%swig_container_with_assignment( %arg(Container), Type );
|
||||||
|
%swig_container_with_equal_operator( %arg(Container), Type );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private macro used to add all extended functions to C/C++
|
||||||
|
* primitive types
|
||||||
|
*
|
||||||
|
* @param Container an STL container, like std::vector (with no class template)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
%define %__swig_container_extend_primtypes( Container )
|
||||||
|
|
||||||
|
%swig_container_extend( %arg( Container ), bool );
|
||||||
|
%swig_container_extend( %arg( Container ), char );
|
||||||
|
%swig_container_extend( %arg( Container ), short );
|
||||||
|
%swig_container_extend( %arg( Container ), int );
|
||||||
|
%swig_container_extend( %arg( Container ), unsigned short );
|
||||||
|
%swig_container_extend( %arg( Container ), unsigned int );
|
||||||
|
%swig_container_extend( %arg( Container ), float );
|
||||||
|
%swig_container_extend( %arg( Container ), double );
|
||||||
|
%swig_container_extend( %arg( Container ), std::complex );
|
||||||
|
%swig_container_extend( %arg( Container ), std::string );
|
||||||
|
%swig_container_extend( %arg( Container ), swig::GC_VALUE );
|
||||||
|
%swig_container_extend( %arg( Container ), swig::GC_VALUE );
|
||||||
|
|
||||||
|
%enddef
|
||||||
|
|
||||||
|
|
||||||
|
%__swig_container_extend_primtypes( std::vector );
|
||||||
|
%__swig_container_extend_primtypes( std::set );
|
||||||
|
%__swig_container_extend_primtypes( std::list );
|
||||||
|
%__swig_container_extend_primtypes( std::deque );
|
||||||
|
|
||||||
|
|
@ -130,7 +130,7 @@ const char* Ruby_Format_TypeError( const char* msg,
|
||||||
{
|
{
|
||||||
str = rb_str_cat2( str, "\n\tin SWIG method '" );
|
str = rb_str_cat2( str, "\n\tin SWIG method '" );
|
||||||
str = rb_str_cat2( str, name );
|
str = rb_str_cat2( str, name );
|
||||||
str = rb_str_cat2( str, "'\n" );
|
str = rb_str_cat2( str, "'" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return StringValuePtr( str );
|
return StringValuePtr( str );
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
*
|
*
|
||||||
* rubyiterators.swg
|
* rubyiterators.swg
|
||||||
*
|
*
|
||||||
* Implement a ruby 'output' iterator for Ruby.
|
* Implement a C++ 'output' iterator for Ruby.
|
||||||
*
|
*
|
||||||
* Users can derive form the RubySwigIterator to implemet their
|
* Users can derive form the RubySwigIterator to implemet their
|
||||||
* own iterators. As an example (real one since we use it for STL/STD
|
* own iterators. As an example (real one since we use it for STL/STD
|
||||||
|
|
@ -14,6 +14,10 @@
|
||||||
|
|
||||||
%include <std_common.i>
|
%include <std_common.i>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class used to represent all iterators of STL containers.
|
||||||
|
*/
|
||||||
%fragment("RubySwigIterator","header") {
|
%fragment("RubySwigIterator","header") {
|
||||||
namespace swig {
|
namespace swig {
|
||||||
struct stop_iteration {
|
struct stop_iteration {
|
||||||
|
|
@ -34,9 +38,6 @@ namespace swig {
|
||||||
// Access iterator method, required by Ruby
|
// Access iterator method, required by Ruby
|
||||||
virtual VALUE value() const = 0;
|
virtual VALUE value() const = 0;
|
||||||
|
|
||||||
// // Set referenced object
|
|
||||||
// virtual bool set(VALUE v) = 0;
|
|
||||||
|
|
||||||
// Forward iterator method, required by Ruby
|
// Forward iterator method, required by Ruby
|
||||||
virtual RubySwigIterator *incr(size_t n = 1) = 0;
|
virtual RubySwigIterator *incr(size_t n = 1) = 0;
|
||||||
|
|
||||||
|
|
@ -60,6 +61,11 @@ namespace swig {
|
||||||
// C++ common/needed methods
|
// C++ common/needed methods
|
||||||
virtual RubySwigIterator *copy() const = 0;
|
virtual RubySwigIterator *copy() const = 0;
|
||||||
|
|
||||||
|
virtual VALUE __deref__()
|
||||||
|
{
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
VALUE next()
|
VALUE next()
|
||||||
{
|
{
|
||||||
VALUE obj = value();
|
VALUE obj = value();
|
||||||
|
|
@ -126,8 +132,14 @@ namespace swig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
%fragment("RubySwigIterator_T","header",fragment="RubySwigIterator",fragment="StdTraits",fragment="StdIteratorTraits") {
|
%fragment("RubySwigIterator_T","header",fragment="RubySwigIterator",fragment="StdTraits",fragment="StdIteratorTraits") {
|
||||||
namespace swig {
|
namespace swig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base classes for all custom iterators.
|
||||||
|
*
|
||||||
|
*/
|
||||||
template<typename OutIterator>
|
template<typename OutIterator>
|
||||||
class RubySwigIterator_T : public RubySwigIterator
|
class RubySwigIterator_T : public RubySwigIterator
|
||||||
{
|
{
|
||||||
|
|
@ -182,6 +194,11 @@ namespace swig {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterator class for a const_iterator with no end() boundaries.
|
||||||
|
*
|
||||||
|
*/
|
||||||
template<typename OutIterator,
|
template<typename OutIterator,
|
||||||
typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
|
typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
|
||||||
typename FromOper = from_oper<ValueType> >
|
typename FromOper = from_oper<ValueType> >
|
||||||
|
|
@ -203,14 +220,6 @@ namespace swig {
|
||||||
return from(static_cast<const value_type&>(*(base::current)));
|
return from(static_cast<const value_type&>(*(base::current)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual bool set(VALUE v) {
|
|
||||||
// value_type val;
|
|
||||||
// if ( !asval(v, &val) ) return SWIG_ERROR;
|
|
||||||
// *(base::current) = val;
|
|
||||||
// return SWIG_OK;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
RubySwigIterator *copy() const
|
RubySwigIterator *copy() const
|
||||||
{
|
{
|
||||||
return new self_type(*this);
|
return new self_type(*this);
|
||||||
|
|
@ -233,6 +242,11 @@ namespace swig {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterator class for a const_iterator where begin() and end() boundaries are known.
|
||||||
|
*
|
||||||
|
*/
|
||||||
template<typename OutIterator,
|
template<typename OutIterator,
|
||||||
typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
|
typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
|
||||||
typename FromOper = from_oper<ValueType> >
|
typename FromOper = from_oper<ValueType> >
|
||||||
|
|
@ -258,13 +272,6 @@ namespace swig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual bool set(VALUE v) {
|
|
||||||
// value_type val;
|
|
||||||
// if ( !asval(v, &val) ) return SWIG_ERROR;
|
|
||||||
// *(base::current) = val;
|
|
||||||
// return SWIG_OK;
|
|
||||||
// }
|
|
||||||
|
|
||||||
RubySwigIterator *copy() const
|
RubySwigIterator *copy() const
|
||||||
{
|
{
|
||||||
return new self_type(*this);
|
return new self_type(*this);
|
||||||
|
|
@ -299,6 +306,12 @@ namespace swig {
|
||||||
out_iterator end;
|
out_iterator end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function used to wrap a bounded const_iterator. This is to be used in
|
||||||
|
* a %typemap(out), for example.
|
||||||
|
*
|
||||||
|
*/
|
||||||
template<typename OutIter>
|
template<typename OutIter>
|
||||||
inline RubySwigIterator*
|
inline RubySwigIterator*
|
||||||
make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, VALUE seq = Qnil)
|
make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, VALUE seq = Qnil)
|
||||||
|
|
@ -306,6 +319,11 @@ namespace swig {
|
||||||
return new RubySwigIteratorClosed_T<OutIter>(current, begin, end, seq);
|
return new RubySwigIteratorClosed_T<OutIter>(current, begin, end, seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function used to wrap an unbounded const_iterator. This is to be used in
|
||||||
|
* a %typemap(out), for example.
|
||||||
|
*
|
||||||
|
*/
|
||||||
template<typename OutIter>
|
template<typename OutIter>
|
||||||
inline RubySwigIterator*
|
inline RubySwigIterator*
|
||||||
make_output_iterator(const OutIter& current, VALUE seq = Qnil)
|
make_output_iterator(const OutIter& current, VALUE seq = Qnil)
|
||||||
|
|
@ -317,6 +335,11 @@ namespace swig {
|
||||||
|
|
||||||
|
|
||||||
%fragment("RubySwigIterator");
|
%fragment("RubySwigIterator");
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// This part is just so SWIG is aware of the base abstract iterator class.
|
||||||
|
//
|
||||||
namespace swig
|
namespace swig
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
@ -365,9 +388,6 @@ namespace swig
|
||||||
// Access iterator method, required by Ruby
|
// Access iterator method, required by Ruby
|
||||||
virtual VALUE value() const = 0;
|
virtual VALUE value() const = 0;
|
||||||
|
|
||||||
// // Set referenced object, required by Ruby
|
|
||||||
// virtual bool set(VALUE val) = 0;
|
|
||||||
|
|
||||||
// Forward iterator method, required by Ruby
|
// Forward iterator method, required by Ruby
|
||||||
virtual RubySwigIterator *incr(size_t n = 1) = 0;
|
virtual RubySwigIterator *incr(size_t n = 1) = 0;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue