You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
5.8 KiB
217 lines
5.8 KiB
5 years ago
|
/*
|
||
|
Sets
|
||
|
*/
|
||
|
|
||
|
%fragment("StdSetTraits","header",fragment="StdSequenceTraits")
|
||
|
%{
|
||
|
namespace swig {
|
||
|
template <class RubySeq, class T>
|
||
|
inline void
|
||
|
assign(const RubySeq& rubyseq, std::set<T>* seq) {
|
||
|
#ifdef SWIG_STD_NOINSERT_TEMPLATE_STL
|
||
|
typedef typename RubySeq::value_type value_type;
|
||
|
typename RubySeq::const_iterator it = rubyseq.begin();
|
||
|
for (;it != rubyseq.end(); ++it) {
|
||
|
seq->insert(seq->end(),(value_type)(*it));
|
||
|
}
|
||
|
#else
|
||
|
seq->insert(rubyseq.begin(), rubyseq.end());
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
struct traits_asptr<std::set<T> > {
|
||
|
static int asptr(VALUE obj, std::set<T> **s) {
|
||
|
return traits_asptr_stdseq<std::set<T> >::asptr(obj, s);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <class T>
|
||
|
struct traits_from<std::set<T> > {
|
||
|
static VALUE from(const std::set<T>& vec) {
|
||
|
return traits_from_stdseq<std::set<T> >::from(vec);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Set 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 SetIteratorOpen_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 SetIteratorOpen_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
|
||
|
|
||
|
public:
|
||
|
SetIteratorOpen_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)));
|
||
|
}
|
||
|
|
||
|
// no setValue allowed
|
||
|
|
||
|
Iterator *dup() const
|
||
|
{
|
||
|
return new self_type(*this);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Set 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 SetIteratorClosed_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 SetIteratorClosed_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:
|
||
|
SetIteratorClosed_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)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// no setValue allowed
|
||
|
|
||
|
|
||
|
Iterator *dup() const
|
||
|
{
|
||
|
return new self_type(*this);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
nonconst_iter begin;
|
||
|
nonconst_iter end;
|
||
|
};
|
||
|
|
||
|
// Template specialization to construct a closed iterator for sets
|
||
|
// this turns a nonconst iterator into a const one for ruby to avoid
|
||
|
// allowing the user to change the value
|
||
|
template< typename InOutIter >
|
||
|
inline Iterator*
|
||
|
make_set_nonconst_iterator(const InOutIter& current,
|
||
|
const InOutIter& begin,
|
||
|
const InOutIter& end,
|
||
|
VALUE seq = Qnil)
|
||
|
{
|
||
|
return new SetIteratorClosed_T< InOutIter >(current,
|
||
|
begin, end, seq);
|
||
|
}
|
||
|
|
||
|
// Template specialization to construct an open iterator for sets
|
||
|
// this turns a nonconst iterator into a const one for ruby to avoid
|
||
|
// allowing the user to change the value
|
||
|
template< typename InOutIter >
|
||
|
inline Iterator*
|
||
|
make_set_nonconst_iterator(const InOutIter& current,
|
||
|
VALUE seq = Qnil)
|
||
|
{
|
||
|
return new SetIteratorOpen_T< InOutIter >(current, seq);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
%}
|
||
|
|
||
|
|
||
|
%define %swig_set_methods(set...)
|
||
|
|
||
|
%swig_sequence_methods_common(%arg(set));
|
||
|
|
||
|
%fragment("RubyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool),fragment="RubySequence_Cont") {}
|
||
|
|
||
|
// Redefine std::set iterator/reverse_iterator typemap
|
||
|
%typemap(out,noblock=1) iterator, reverse_iterator {
|
||
|
$result = SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,const $type &),
|
||
|
self),
|
||
|
swig::Iterator::descriptor(),SWIG_POINTER_OWN);
|
||
|
}
|
||
|
|
||
|
// Redefine std::set std::pair<iterator, bool> typemap
|
||
|
%typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator")
|
||
|
std::pair<iterator, bool> {
|
||
|
$result = rb_ary_new2(2);
|
||
|
RARRAY_PTR($result)[0] = SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,$type &).first),
|
||
|
swig::Iterator::descriptor(),SWIG_POINTER_OWN);
|
||
|
RARRAY_PTR($result)[1] = SWIG_From(bool)(%static_cast($1,const $type &).second);
|
||
|
RARRAY_LEN($result) = 2;
|
||
|
}
|
||
|
|
||
|
%extend {
|
||
|
%alias push "<<";
|
||
|
value_type push(const value_type& x) {
|
||
|
self->insert(x);
|
||
|
return x;
|
||
|
}
|
||
|
|
||
|
bool __contains__(const value_type& x) {
|
||
|
return self->find(x) != self->end();
|
||
|
}
|
||
|
|
||
|
value_type __getitem__(difference_type i) const throw (std::out_of_range) {
|
||
|
return *(swig::cgetpos(self, i));
|
||
|
}
|
||
|
|
||
|
};
|
||
|
%enddef
|
||
|
|
||
|
|
||
|
%mixin std::set "Enumerable";
|
||
|
|
||
|
|
||
|
|
||
|
%rename("delete") std::set::__delete__;
|
||
|
%rename("reject!") std::set::reject_bang;
|
||
|
%rename("map!") std::set::map_bang;
|
||
|
%rename("empty?") std::set::empty;
|
||
|
%rename("include?" ) std::set::__contains__ const;
|
||
|
%rename("has_key?" ) std::set::has_key const;
|
||
|
|
||
|
%alias std::set::push "<<";
|
||
|
|
||
|
|
||
|
%include <std/std_set.i>
|
||
|
|