mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-09-01 23:19:18 +00:00
1
This commit is contained in:
@@ -0,0 +1,935 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* See the LICENSE file for information on copyright, usage and redistribution
|
||||
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
|
||||
*
|
||||
* rubyiterators.swg
|
||||
*
|
||||
* Implement a C++ 'output' iterator for Ruby.
|
||||
*
|
||||
* Users can derive form the Iterator to implemet their
|
||||
* own iterators. As an example (real one since we use it for STL/STD
|
||||
* containers), the template Iterator_T does the
|
||||
* implementation for generic C++ iterators.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
%include <std_common.i>
|
||||
|
||||
|
||||
%fragment("ConstIterator","header") {
|
||||
namespace swig {
|
||||
struct stop_iteration {
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract base class used to represent all iterators of STL containers.
|
||||
*/
|
||||
struct ConstIterator {
|
||||
public:
|
||||
typedef ConstIterator self_type;
|
||||
|
||||
protected:
|
||||
GC_VALUE _seq;
|
||||
|
||||
protected:
|
||||
ConstIterator(VALUE seq) : _seq(seq)
|
||||
{
|
||||
}
|
||||
|
||||
// Random access iterator methods, but not required in Ruby
|
||||
virtual ptrdiff_t distance(const ConstIterator &x) const
|
||||
{
|
||||
throw std::invalid_argument("distance not supported");
|
||||
}
|
||||
|
||||
virtual bool equal (const ConstIterator &x) const
|
||||
{
|
||||
throw std::invalid_argument("equal not supported");
|
||||
}
|
||||
|
||||
virtual self_type* advance(ptrdiff_t n)
|
||||
{
|
||||
throw std::invalid_argument("advance not supported");
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~ConstIterator() {}
|
||||
|
||||
// Access iterator method, required by Ruby
|
||||
virtual VALUE value() const {
|
||||
throw std::invalid_argument("value not supported");
|
||||
return Qnil;
|
||||
};
|
||||
|
||||
virtual VALUE setValue( const VALUE& v ) {
|
||||
throw std::invalid_argument("value= not supported");
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
virtual self_type* next( size_t n = 1 )
|
||||
{
|
||||
return this->advance( n );
|
||||
}
|
||||
|
||||
virtual self_type* previous( size_t n = 1 )
|
||||
{
|
||||
ptrdiff_t nn = n;
|
||||
return this->advance( -nn );
|
||||
}
|
||||
|
||||
virtual VALUE to_s() const {
|
||||
throw std::invalid_argument("to_s not supported");
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
virtual VALUE inspect() const {
|
||||
throw std::invalid_argument("inspect not supported");
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
virtual ConstIterator *dup() const
|
||||
{
|
||||
throw std::invalid_argument("dup not supported");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// C++ common/needed methods. We emulate a bidirectional
|
||||
// operator, to be compatible with all the STL.
|
||||
// The iterator traits will then tell the STL what type of
|
||||
// iterator we really are.
|
||||
//
|
||||
ConstIterator() : _seq( Qnil )
|
||||
{
|
||||
}
|
||||
|
||||
ConstIterator( const self_type& b ) : _seq( b._seq )
|
||||
{
|
||||
}
|
||||
|
||||
self_type& operator=( const self_type& b )
|
||||
{
|
||||
_seq = b._seq;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator == (const ConstIterator& x) const
|
||||
{
|
||||
return equal(x);
|
||||
}
|
||||
|
||||
bool operator != (const ConstIterator& x) const
|
||||
{
|
||||
return ! operator==(x);
|
||||
}
|
||||
|
||||
// Pre-decrement operator
|
||||
self_type& operator--()
|
||||
{
|
||||
return *previous();
|
||||
}
|
||||
|
||||
// Pre-increment operator
|
||||
self_type& operator++()
|
||||
{
|
||||
return *next();
|
||||
}
|
||||
|
||||
// Post-decrement operator
|
||||
self_type operator--(int)
|
||||
{
|
||||
self_type r = *this;
|
||||
previous();
|
||||
return r;
|
||||
}
|
||||
|
||||
// Post-increment operator
|
||||
self_type operator++(int)
|
||||
{
|
||||
self_type r = *this;
|
||||
next();
|
||||
return r;
|
||||
}
|
||||
|
||||
ConstIterator& operator += (ptrdiff_t n)
|
||||
{
|
||||
return *advance(n);
|
||||
}
|
||||
|
||||
ConstIterator& operator -= (ptrdiff_t n)
|
||||
{
|
||||
return *advance(-n);
|
||||
}
|
||||
|
||||
ConstIterator* operator + (ptrdiff_t n) const
|
||||
{
|
||||
return dup()->advance(n);
|
||||
}
|
||||
|
||||
ConstIterator* operator - (ptrdiff_t n) const
|
||||
{
|
||||
return dup()->advance(-n);
|
||||
}
|
||||
|
||||
ptrdiff_t operator - (const ConstIterator& x) const
|
||||
{
|
||||
return x.distance(*this);
|
||||
}
|
||||
|
||||
static swig_type_info* descriptor() {
|
||||
static int init = 0;
|
||||
static swig_type_info* desc = 0;
|
||||
if (!init) {
|
||||
desc = SWIG_TypeQuery("swig::ConstIterator *");
|
||||
init = 1;
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Abstract base class used to represent all non-const iterators of STL containers.
|
||||
*
|
||||
*/
|
||||
struct Iterator : public ConstIterator {
|
||||
public:
|
||||
typedef Iterator self_type;
|
||||
|
||||
protected:
|
||||
Iterator(VALUE seq) : ConstIterator(seq)
|
||||
{
|
||||
}
|
||||
|
||||
virtual self_type* advance(ptrdiff_t n)
|
||||
{
|
||||
throw std::invalid_argument("operation not supported");
|
||||
}
|
||||
|
||||
public:
|
||||
static swig_type_info* descriptor() {
|
||||
static int init = 0;
|
||||
static swig_type_info* desc = 0;
|
||||
if (!init) {
|
||||
desc = SWIG_TypeQuery("swig::Iterator *");
|
||||
init = 1;
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
virtual Iterator *dup() const
|
||||
{
|
||||
throw std::invalid_argument("dup not supported");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual self_type* next( size_t n = 1 )
|
||||
{
|
||||
return this->advance( n );
|
||||
}
|
||||
|
||||
virtual self_type* previous( size_t n = 1 )
|
||||
{
|
||||
ptrdiff_t nn = n;
|
||||
return this->advance( -nn );
|
||||
}
|
||||
|
||||
bool operator == (const ConstIterator& x) const
|
||||
{
|
||||
return equal(x);
|
||||
}
|
||||
|
||||
bool operator != (const Iterator& x) const
|
||||
{
|
||||
return ! operator==(x);
|
||||
}
|
||||
|
||||
Iterator& operator += (ptrdiff_t n)
|
||||
{
|
||||
return *advance(n);
|
||||
}
|
||||
|
||||
Iterator& operator -= (ptrdiff_t n)
|
||||
{
|
||||
return *advance(-n);
|
||||
}
|
||||
|
||||
Iterator* operator + (ptrdiff_t n) const
|
||||
{
|
||||
return dup()->advance(n);
|
||||
}
|
||||
|
||||
Iterator* operator - (ptrdiff_t n) const
|
||||
{
|
||||
return dup()->advance(-n);
|
||||
}
|
||||
|
||||
ptrdiff_t operator - (const Iterator& x) const
|
||||
{
|
||||
return x.distance(*this);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
%fragment("ConstIterator_T","header",fragment="ConstIterator",fragment="StdTraits",fragment="StdIteratorTraits") {
|
||||
namespace swig {
|
||||
|
||||
/**
|
||||
* Templated base classes for all custom const_iterators.
|
||||
*
|
||||
*/
|
||||
template<typename OutConstIterator>
|
||||
class ConstIterator_T : public ConstIterator
|
||||
{
|
||||
public:
|
||||
typedef OutConstIterator const_iter;
|
||||
typedef typename std::iterator_traits<const_iter>::value_type value_type;
|
||||
typedef ConstIterator_T<const_iter> self_type;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
virtual bool equal (const ConstIterator &iter) const
|
||||
{
|
||||
const self_type *iters = dynamic_cast<const self_type *>(&iter);
|
||||
if (iters) {
|
||||
return (current == iters->get_current());
|
||||
} else {
|
||||
throw std::invalid_argument("bad iterator type");
|
||||
}
|
||||
}
|
||||
|
||||
virtual ptrdiff_t distance(const ConstIterator &iter) const
|
||||
{
|
||||
const self_type *iters = dynamic_cast<const self_type *>(&iter);
|
||||
if (iters) {
|
||||
return std::distance(current, iters->get_current());
|
||||
} else {
|
||||
throw std::invalid_argument("bad iterator type");
|
||||
}
|
||||
}
|
||||
|
||||
virtual ConstIterator* advance(ptrdiff_t n)
|
||||
{
|
||||
std::advance( current, n );
|
||||
return this;
|
||||
}
|
||||
|
||||
public:
|
||||
ConstIterator_T() : ConstIterator(Qnil)
|
||||
{
|
||||
}
|
||||
|
||||
ConstIterator_T(const_iter curr, VALUE seq = Qnil)
|
||||
: ConstIterator(seq), current(curr)
|
||||
{
|
||||
}
|
||||
|
||||
const const_iter& get_current() const
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
const value_type& operator*() const
|
||||
{
|
||||
return *current;
|
||||
}
|
||||
|
||||
virtual VALUE inspect() const
|
||||
{
|
||||
VALUE ret = rb_str_new2("#<");
|
||||
ret = rb_str_cat2( ret, rb_obj_classname(_seq) );
|
||||
ret = rb_str_cat2( ret, "::const_iterator " );
|
||||
VALUE cur = value();
|
||||
ret = rb_str_concat( ret, rb_inspect(cur) );
|
||||
ret = rb_str_cat2( ret, ">" );
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual VALUE to_s() const
|
||||
{
|
||||
VALUE ret = rb_str_new2( rb_obj_classname(_seq) );
|
||||
ret = rb_str_cat2( ret, "::const_iterator " );
|
||||
VALUE cur = value();
|
||||
ret = rb_str_concat( ret, rb_obj_as_string(cur) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected:
|
||||
const_iter current;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Templated base classes for all custom non-const iterators.
|
||||
*
|
||||
*/
|
||||
template<typename InOutIterator>
|
||||
class Iterator_T : public Iterator
|
||||
{
|
||||
public:
|
||||
typedef InOutIterator nonconst_iter;
|
||||
|
||||
// Make this class iterator STL compatible, by using iterator_traits
|
||||
typedef typename std::iterator_traits<nonconst_iter >::iterator_category iterator_category;
|
||||
typedef typename std::iterator_traits<nonconst_iter >::value_type value_type;
|
||||
typedef typename std::iterator_traits<nonconst_iter >::difference_type difference_type;
|
||||
typedef typename std::iterator_traits<nonconst_iter >::pointer pointer;
|
||||
typedef typename std::iterator_traits<nonconst_iter >::reference reference;
|
||||
|
||||
typedef Iterator base;
|
||||
typedef Iterator_T< nonconst_iter > self_type;
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool equal (const ConstIterator &iter) const
|
||||
{
|
||||
const self_type *iters = dynamic_cast<const self_type *>(&iter);
|
||||
if (iters) {
|
||||
return (current == iters->get_current());
|
||||
} else {
|
||||
throw std::invalid_argument("bad iterator type");
|
||||
}
|
||||
}
|
||||
|
||||
virtual ptrdiff_t distance(const ConstIterator &iter) const
|
||||
{
|
||||
const self_type *iters = dynamic_cast<const self_type *>(&iter);
|
||||
if (iters) {
|
||||
return std::distance(current, iters->get_current());
|
||||
} else {
|
||||
throw std::invalid_argument("bad iterator type");
|
||||
}
|
||||
}
|
||||
|
||||
virtual Iterator* advance(ptrdiff_t n)
|
||||
{
|
||||
std::advance( current, n );
|
||||
return this;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Iterator_T(nonconst_iter curr, VALUE seq = Qnil)
|
||||
: Iterator(seq), current(curr)
|
||||
{
|
||||
}
|
||||
|
||||
const nonconst_iter& get_current() const
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
self_type& operator=( const self_type& b )
|
||||
{
|
||||
base::operator=( b );
|
||||
return *this;
|
||||
}
|
||||
|
||||
self_type& operator=( const value_type& b )
|
||||
{
|
||||
*current = b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const value_type& operator*() const
|
||||
{
|
||||
return *current;
|
||||
}
|
||||
|
||||
value_type& operator*()
|
||||
{
|
||||
return *current;
|
||||
}
|
||||
|
||||
virtual VALUE inspect() const
|
||||
{
|
||||
VALUE ret = rb_str_new2("#<");
|
||||
ret = rb_str_cat2( ret, rb_obj_classname(_seq) );
|
||||
ret = rb_str_cat2( ret, "::iterator " );
|
||||
VALUE cur = value();
|
||||
ret = rb_str_concat( ret, rb_inspect(cur) );
|
||||
ret = rb_str_cat2( ret, ">" );
|
||||
return ret;
|
||||
}
|
||||
|
||||
virtual VALUE to_s() const
|
||||
{
|
||||
VALUE ret = rb_str_new2( rb_obj_classname(_seq) );
|
||||
ret = rb_str_cat2( ret, "::iterator " );
|
||||
VALUE cur = value();
|
||||
ret = rb_str_concat( ret, rb_obj_as_string(cur) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected:
|
||||
nonconst_iter current;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Auxiliary functor to store the value of a ruby object inside
|
||||
* a reference of a compatible C++ type. ie: Ruby -> C++
|
||||
*
|
||||
*/
|
||||
template <class ValueType>
|
||||
struct asval_oper
|
||||
{
|
||||
typedef ValueType value_type;
|
||||
typedef bool result_type;
|
||||
bool operator()(VALUE obj, value_type& v) const
|
||||
{
|
||||
return ( swig::asval< value_type >(obj, &v) == SWIG_OK );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Auxiliary functor to return a ruby object from a C++ type.
|
||||
* ie: C++ -> Ruby
|
||||
*
|
||||
*/
|
||||
template <class ValueType>
|
||||
struct from_oper
|
||||
{
|
||||
typedef const ValueType& argument_type;
|
||||
typedef VALUE result_type;
|
||||
result_type operator()(argument_type v) const
|
||||
{
|
||||
return swig::from(v);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ConstIterator class for a const_iterator with no end() boundaries.
|
||||
*
|
||||
*/
|
||||
template<typename OutConstIterator,
|
||||
typename ValueType = typename std::iterator_traits<OutConstIterator>::value_type,
|
||||
typename FromOper = from_oper<ValueType> >
|
||||
class ConstIteratorOpen_T : public ConstIterator_T<OutConstIterator>
|
||||
{
|
||||
public:
|
||||
FromOper from;
|
||||
typedef OutConstIterator const_iter;
|
||||
typedef ValueType value_type;
|
||||
typedef ConstIterator_T<const_iter> base;
|
||||
typedef ConstIteratorOpen_T<OutConstIterator, ValueType, FromOper> self_type;
|
||||
|
||||
ConstIteratorOpen_T(const_iter curr, VALUE seq = Qnil)
|
||||
: ConstIterator_T<OutConstIterator>(curr, seq)
|
||||
{
|
||||
}
|
||||
|
||||
virtual VALUE value() const {
|
||||
return from(static_cast<const value_type&>(*(base::current)));
|
||||
}
|
||||
|
||||
ConstIterator *dup() const
|
||||
{
|
||||
return new self_type(*this);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterator class for an iterator with no end() boundaries.
|
||||
*
|
||||
*/
|
||||
template<typename InOutIterator,
|
||||
typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
|
||||
typename FromOper = from_oper<ValueType>,
|
||||
typename AsvalOper = asval_oper<ValueType> >
|
||||
class IteratorOpen_T : public Iterator_T<InOutIterator>
|
||||
{
|
||||
public:
|
||||
FromOper from;
|
||||
AsvalOper asval;
|
||||
typedef InOutIterator nonconst_iter;
|
||||
typedef ValueType value_type;
|
||||
typedef Iterator_T<nonconst_iter> base;
|
||||
typedef IteratorOpen_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
|
||||
|
||||
public:
|
||||
IteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil)
|
||||
: Iterator_T<InOutIterator>(curr, seq)
|
||||
{
|
||||
}
|
||||
|
||||
virtual VALUE value() const {
|
||||
return from(static_cast<const value_type&>(*(base::current)));
|
||||
}
|
||||
|
||||
virtual VALUE setValue( const VALUE& v )
|
||||
{
|
||||
value_type& dst = *base::current;
|
||||
if ( asval(v, dst) ) return v;
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
Iterator *dup() const
|
||||
{
|
||||
return new self_type(*this);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* ConstIterator class for a const_iterator where begin() and end() boundaries are known.
|
||||
*
|
||||
*/
|
||||
template<typename OutConstIterator,
|
||||
typename ValueType = typename std::iterator_traits<OutConstIterator>::value_type,
|
||||
typename FromOper = from_oper<ValueType> >
|
||||
class ConstIteratorClosed_T : public ConstIterator_T<OutConstIterator>
|
||||
{
|
||||
public:
|
||||
FromOper from;
|
||||
typedef OutConstIterator const_iter;
|
||||
typedef ValueType value_type;
|
||||
typedef ConstIterator_T<const_iter> base;
|
||||
typedef ConstIteratorClosed_T<OutConstIterator, ValueType, FromOper> self_type;
|
||||
|
||||
protected:
|
||||
virtual ConstIterator* advance(ptrdiff_t n)
|
||||
{
|
||||
std::advance( base::current, n );
|
||||
if ( base::current == end )
|
||||
throw stop_iteration();
|
||||
return this;
|
||||
}
|
||||
|
||||
public:
|
||||
ConstIteratorClosed_T(const_iter curr, const_iter first,
|
||||
const_iter last, VALUE seq = Qnil)
|
||||
: ConstIterator_T<OutConstIterator>(curr, seq), begin(first), end(last)
|
||||
{
|
||||
}
|
||||
|
||||
virtual VALUE value() const {
|
||||
if (base::current == end) {
|
||||
throw stop_iteration();
|
||||
} else {
|
||||
return from(static_cast<const value_type&>(*(base::current)));
|
||||
}
|
||||
}
|
||||
|
||||
ConstIterator *dup() const
|
||||
{
|
||||
return new self_type(*this);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
const_iter begin;
|
||||
const_iter end;
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterator class for a iterator where begin() and end() boundaries are known.
|
||||
*
|
||||
*/
|
||||
template<typename InOutIterator,
|
||||
typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
|
||||
typename FromOper = from_oper<ValueType>,
|
||||
typename AsvalOper = asval_oper<ValueType> >
|
||||
class IteratorClosed_T : public Iterator_T<InOutIterator>
|
||||
{
|
||||
public:
|
||||
FromOper from;
|
||||
AsvalOper asval;
|
||||
typedef InOutIterator nonconst_iter;
|
||||
typedef ValueType value_type;
|
||||
typedef Iterator_T<nonconst_iter> base;
|
||||
typedef IteratorClosed_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
|
||||
|
||||
protected:
|
||||
virtual Iterator* advance(ptrdiff_t n)
|
||||
{
|
||||
std::advance( base::current, n );
|
||||
if ( base::current == end )
|
||||
throw stop_iteration();
|
||||
return this;
|
||||
}
|
||||
|
||||
public:
|
||||
IteratorClosed_T(nonconst_iter curr, nonconst_iter first,
|
||||
nonconst_iter last, VALUE seq = Qnil)
|
||||
: Iterator_T<InOutIterator>(curr, seq), begin(first), end(last)
|
||||
{
|
||||
}
|
||||
|
||||
virtual VALUE value() const {
|
||||
if (base::current == end) {
|
||||
throw stop_iteration();
|
||||
} else {
|
||||
return from(static_cast<const value_type&>(*(base::current)));
|
||||
}
|
||||
}
|
||||
|
||||
// Iterator setter method, required by Ruby
|
||||
virtual VALUE setValue( const VALUE& v )
|
||||
{
|
||||
if (base::current == end)
|
||||
throw stop_iteration();
|
||||
|
||||
value_type& dst = *base::current;
|
||||
if ( asval( v, dst ) ) return v;
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
Iterator *dup() const
|
||||
{
|
||||
return new self_type(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
nonconst_iter begin;
|
||||
nonconst_iter end;
|
||||
};
|
||||
|
||||
/* Partial specialization for bools which don't allow de-referencing */
|
||||
template< typename InOutIterator, typename FromOper, typename AsvalOper >
|
||||
class IteratorOpen_T< InOutIterator, bool, FromOper, AsvalOper > :
|
||||
public Iterator_T<InOutIterator>
|
||||
{
|
||||
public:
|
||||
FromOper from;
|
||||
AsvalOper asval;
|
||||
typedef InOutIterator nonconst_iter;
|
||||
typedef bool value_type;
|
||||
typedef Iterator_T<nonconst_iter> base;
|
||||
typedef IteratorOpen_T<InOutIterator, bool, FromOper, AsvalOper> self_type;
|
||||
|
||||
IteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil)
|
||||
: Iterator_T<InOutIterator>(curr, seq)
|
||||
{
|
||||
}
|
||||
|
||||
virtual VALUE value() const {
|
||||
return from(static_cast<const value_type&>(*(base::current)));
|
||||
}
|
||||
|
||||
virtual VALUE setValue( const VALUE& v )
|
||||
{
|
||||
bool tmp = *base::current;
|
||||
if ( asval( v, tmp ) )
|
||||
{
|
||||
*base::current = tmp;
|
||||
return v;
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
Iterator *dup() const
|
||||
{
|
||||
return new self_type(*this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/* Partial specialization for bools which don't allow de-referencing */
|
||||
template< typename InOutIterator, typename FromOper, typename AsvalOper >
|
||||
class IteratorClosed_T< InOutIterator, bool, FromOper, AsvalOper > :
|
||||
public Iterator_T<InOutIterator>
|
||||
{
|
||||
public:
|
||||
FromOper from;
|
||||
AsvalOper asval;
|
||||
typedef InOutIterator nonconst_iter;
|
||||
typedef bool value_type;
|
||||
typedef Iterator_T<nonconst_iter> base;
|
||||
typedef IteratorClosed_T<InOutIterator, bool, FromOper, AsvalOper> self_type;
|
||||
|
||||
protected:
|
||||
virtual Iterator* advance(ptrdiff_t n)
|
||||
{
|
||||
std::advance( base::current, n );
|
||||
if ( base::current == end )
|
||||
throw stop_iteration();
|
||||
return this;
|
||||
}
|
||||
|
||||
public:
|
||||
IteratorClosed_T(nonconst_iter curr, nonconst_iter first,
|
||||
nonconst_iter last, VALUE seq = Qnil)
|
||||
: Iterator_T<InOutIterator>(curr, seq), begin(first), end(last)
|
||||
{
|
||||
}
|
||||
|
||||
virtual VALUE value() const {
|
||||
if (base::current == end) {
|
||||
throw stop_iteration();
|
||||
} else {
|
||||
return from(static_cast<const value_type&>(*(base::current)));
|
||||
}
|
||||
}
|
||||
|
||||
virtual VALUE setValue( const VALUE& v )
|
||||
{
|
||||
if (base::current == end)
|
||||
throw stop_iteration();
|
||||
|
||||
bool tmp = *base::current;
|
||||
if ( asval( v, tmp ) )
|
||||
{
|
||||
*base::current = tmp;
|
||||
return v;
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
Iterator *dup() const
|
||||
{
|
||||
return new self_type(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
nonconst_iter begin;
|
||||
nonconst_iter end;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper function used to wrap a bounded const_iterator. This is to be used in
|
||||
* a %typemap(out), for example.
|
||||
*
|
||||
*/
|
||||
template<typename InOutIter>
|
||||
inline Iterator*
|
||||
make_nonconst_iterator(const InOutIter& current, const InOutIter& begin,
|
||||
const InOutIter& end, VALUE seq = Qnil)
|
||||
{
|
||||
return new IteratorClosed_T<InOutIter>(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 InOutIter>
|
||||
inline Iterator*
|
||||
make_nonconst_iterator(const InOutIter& current, VALUE seq = Qnil)
|
||||
{
|
||||
return new IteratorOpen_T<InOutIter>(current, seq);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function used to wrap a bounded const_iterator. This is to be used in
|
||||
* a %typemap(out), for example.
|
||||
*
|
||||
*/
|
||||
template<typename OutIter>
|
||||
inline ConstIterator*
|
||||
make_const_iterator(const OutIter& current, const OutIter& begin,
|
||||
const OutIter& end, VALUE seq = Qnil)
|
||||
{
|
||||
return new ConstIteratorClosed_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>
|
||||
inline ConstIterator*
|
||||
make_const_iterator(const OutIter& current, VALUE seq = Qnil)
|
||||
{
|
||||
return new ConstIteratorOpen_T<OutIter>(current, seq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
%fragment("ConstIterator");
|
||||
|
||||
|
||||
//
|
||||
// This part is just so SWIG is aware of the base abstract iterator class.
|
||||
//
|
||||
namespace swig
|
||||
{
|
||||
/*
|
||||
Throw a StopIteration exception
|
||||
*/
|
||||
%ignore stop_iteration;
|
||||
struct stop_iteration {};
|
||||
|
||||
%typemap(throws) stop_iteration {
|
||||
(void)$1;
|
||||
SWIG_Ruby_ExceptionType(NULL, Qnil);
|
||||
SWIG_fail;
|
||||
}
|
||||
|
||||
/*
|
||||
Mark methods that return new objects
|
||||
*/
|
||||
%newobject ConstIterator::dup;
|
||||
%newobject ConstIterator::operator + (ptrdiff_t n) const;
|
||||
%newobject ConstIterator::operator - (ptrdiff_t n) const;
|
||||
|
||||
%nodirector ConstIterator;
|
||||
|
||||
%catches(swig::stop_iteration) ConstIterator::value() const;
|
||||
%catches(swig::stop_iteration) ConstIterator::incr(size_t n = 1);
|
||||
%catches(swig::stop_iteration) ConstIterator::decr(size_t n = 1);
|
||||
%catches(std::invalid_argument) ConstIterator::distance(const ConstIterator &x) const;
|
||||
%catches(std::invalid_argument) ConstIterator::equal (const ConstIterator &x) const;
|
||||
%catches(swig::stop_iteration) ConstIterator::next();
|
||||
%catches(swig::stop_iteration) ConstIterator::previous();
|
||||
%catches(swig::stop_iteration) ConstIterator::advance(ptrdiff_t n);
|
||||
%catches(swig::stop_iteration) ConstIterator::operator += (ptrdiff_t n);
|
||||
%catches(swig::stop_iteration) ConstIterator::operator -= (ptrdiff_t n);
|
||||
%catches(swig::stop_iteration) ConstIterator::operator + (ptrdiff_t n) const;
|
||||
%catches(swig::stop_iteration) ConstIterator::operator - (ptrdiff_t n) const;
|
||||
|
||||
|
||||
struct ConstIterator
|
||||
{
|
||||
protected:
|
||||
ConstIterator(VALUE seq);
|
||||
|
||||
public:
|
||||
virtual ~ConstIterator();
|
||||
|
||||
// Access iterator method, required by Ruby
|
||||
virtual VALUE value() const;
|
||||
|
||||
// C++ common/needed methods
|
||||
virtual ConstIterator *dup() const;
|
||||
|
||||
virtual VALUE inspect() const;
|
||||
virtual VALUE to_s() const;
|
||||
|
||||
virtual ConstIterator* next(size_t n = 1);
|
||||
virtual ConstIterator* previous(size_t n = 1);
|
||||
|
||||
bool operator == (const ConstIterator& x) const;
|
||||
ConstIterator* operator + (ptrdiff_t n) const;
|
||||
ConstIterator* operator - (ptrdiff_t n) const;
|
||||
ptrdiff_t operator - (const ConstIterator& x) const;
|
||||
};
|
||||
|
||||
struct Iterator : public ConstIterator
|
||||
{
|
||||
%rename("value=") setValue( const VALUE& v );
|
||||
virtual VALUE setValue( const VALUE& v );
|
||||
|
||||
virtual Iterator *dup() const;
|
||||
|
||||
virtual Iterator* next(size_t n = 1);
|
||||
virtual Iterator* previous(size_t n = 1);
|
||||
|
||||
virtual VALUE inspect() const;
|
||||
virtual VALUE to_s() const;
|
||||
|
||||
bool operator == (const Iterator& x) const;
|
||||
Iterator* operator + (ptrdiff_t n) const;
|
||||
Iterator* operator - (ptrdiff_t n) const;
|
||||
ptrdiff_t operator - (const Iterator& x) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user