diff options
Diffstat (limited to 'trunk/Lib/ruby/std_set.i')
-rw-r--r-- | trunk/Lib/ruby/std_set.i | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/trunk/Lib/ruby/std_set.i b/trunk/Lib/ruby/std_set.i new file mode 100644 index 000000000..09c4404cf --- /dev/null +++ b/trunk/Lib/ruby/std_set.i @@ -0,0 +1,212 @@ +/* + Sets +*/ + +%fragment("StdSetTraits","header",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_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); + 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> + |