| /* | |
| 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<$type>($1, 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($1.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> | |