summaryrefslogtreecommitdiff
path: root/trunk/Lib/ruby/std_set.i
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/Lib/ruby/std_set.i')
-rw-r--r--trunk/Lib/ruby/std_set.i212
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>
+