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 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
/*
Sets
*/
%fragment("StdSetTraits","header",fragment="<stddef.h>",fragment="StdSequenceTraits")
%{
namespace swig {
template <class RubySeq, class T>
inline void
assign(const RubySeq& rubyseq, std::set<T>* seq) {
// seq->insert(rubyseq.begin(), rubyseq.end()); // not used as not always implemented
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));
}
}
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_sequence_methods_extra_set(Sequence...)
%extend {
%alias reject_bang "delete_if";
Sequence* reject_bang() {
if ( !rb_block_given_p() )
rb_raise( rb_eArgError, "no block given" );
for ( Sequence::iterator i = $self->begin(); i != $self->end(); ) {
VALUE r = swig::from< Sequence::value_type >(*i);
Sequence::iterator current = i++;
if ( RTEST( rb_yield(r) ) )
$self->erase(current);
}
return self;
}
}
%enddef
%define %swig_set_methods(set...)
%swig_sequence_methods_common(%arg(set));
%swig_sequence_methods_extra_set(%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);
rb_ary_push($result, SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,$type &).first),
swig::Iterator::descriptor(),SWIG_POINTER_OWN));
rb_ary_push($result, SWIG_From(bool)(%static_cast($1,const $type &).second));
}
%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>
|