PageRenderTime 35ms CodeModel.GetById 28ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Lib/ruby/std_set.i

#
Swig | 212 lines | 160 code | 40 blank | 12 comment | 0 complexity | 5cd736e3fff57519f4ce82d530e00bb3 MD5 | raw file
  1/*
  2  Sets
  3*/
  4
  5%fragment("StdSetTraits","header",fragment="<stddef.h>",fragment="StdSequenceTraits")
  6%{
  7  namespace swig {
  8    template <class RubySeq, class T> 
  9    inline void 
 10    assign(const RubySeq& rubyseq, std::set<T>* seq) {
 11      // seq->insert(rubyseq.begin(), rubyseq.end()); // not used as not always implemented
 12      typedef typename RubySeq::value_type value_type;
 13      typename RubySeq::const_iterator it = rubyseq.begin();
 14      for (;it != rubyseq.end(); ++it) {
 15	seq->insert(seq->end(),(value_type)(*it));
 16      }
 17    }
 18
 19    template <class T>
 20    struct traits_asptr<std::set<T> >  {
 21      static int asptr(VALUE obj, std::set<T> **s) {  
 22	return traits_asptr_stdseq<std::set<T> >::asptr(obj, s);
 23      }
 24    };
 25
 26    template <class T>
 27    struct traits_from<std::set<T> > {
 28      static VALUE from(const std::set<T>& vec) {
 29	return traits_from_stdseq<std::set<T> >::from(vec);
 30      }
 31    };
 32
 33
 34    /** 
 35     * Set Iterator class for an iterator with no end() boundaries.
 36     *
 37     */
 38    template<typename InOutIterator, 
 39	     typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
 40	     typename FromOper = from_oper<ValueType>,
 41	     typename AsvalOper = asval_oper<ValueType> >
 42      class SetIteratorOpen_T :  public Iterator_T<InOutIterator>
 43    {
 44    public:
 45      FromOper  from;
 46      AsvalOper asval;
 47      typedef InOutIterator nonconst_iter;
 48      typedef ValueType value_type;
 49      typedef Iterator_T<nonconst_iter>  base;
 50      typedef SetIteratorOpen_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
 51
 52    public:
 53      SetIteratorOpen_T(nonconst_iter curr, VALUE seq = Qnil)
 54	: Iterator_T<InOutIterator>(curr, seq)
 55      {
 56      }
 57    
 58      virtual VALUE value() const {
 59	return from(static_cast<const value_type&>(*(base::current)));
 60      }
 61
 62      // no setValue allowed
 63    
 64      Iterator *dup() const
 65      {
 66	return new self_type(*this);
 67      }
 68    };
 69
 70
 71    /** 
 72     * Set Iterator class for a iterator where begin() and end() boundaries
 73       are known.
 74     *
 75     */
 76    template<typename InOutIterator, 
 77	     typename ValueType = typename std::iterator_traits<InOutIterator>::value_type,
 78	     typename FromOper = from_oper<ValueType>,
 79	     typename AsvalOper = asval_oper<ValueType> >
 80    class SetIteratorClosed_T :  public Iterator_T<InOutIterator>
 81    {
 82    public:
 83      FromOper   from;
 84      AsvalOper asval;
 85      typedef InOutIterator nonconst_iter;
 86      typedef ValueType value_type;
 87      typedef Iterator_T<nonconst_iter>  base;
 88      typedef SetIteratorClosed_T<InOutIterator, ValueType, FromOper, AsvalOper> self_type;
 89    
 90    protected:
 91      virtual Iterator* advance(ptrdiff_t n)
 92      {
 93	std::advance( base::current, n );
 94	if ( base::current == end )
 95	  throw stop_iteration();
 96	return this;
 97      }
 98
 99    public:
100      SetIteratorClosed_T(nonconst_iter curr, nonconst_iter first, 
101		       nonconst_iter last, VALUE seq = Qnil)
102	: Iterator_T<InOutIterator>(curr, seq), begin(first), end(last)
103      {
104      }
105    
106      virtual VALUE value() const {
107	if (base::current == end) {
108	  throw stop_iteration();
109	} else {
110	  return from(static_cast<const value_type&>(*(base::current)));
111	}
112      }
113
114      // no setValue allowed
115    
116    
117      Iterator *dup() const
118      {
119	return new self_type(*this);
120      }
121
122    private:
123      nonconst_iter begin;
124      nonconst_iter end;
125    };
126
127    // Template specialization to construct a closed iterator for sets
128    // this turns a nonconst iterator into a const one for ruby to avoid
129    // allowing the user to change the value
130    template< typename InOutIter >
131    inline Iterator*
132    make_set_nonconst_iterator(const InOutIter& current, 
133			       const InOutIter& begin,
134			       const InOutIter& end, 
135			       VALUE seq = Qnil)
136    {
137      return new SetIteratorClosed_T< InOutIter >(current, 
138						  begin, end, seq);
139    }
140
141    // Template specialization to construct an open iterator for sets
142    // this turns a nonconst iterator into a const one for ruby to avoid
143    // allowing the user to change the value
144    template< typename InOutIter >
145    inline Iterator*
146    make_set_nonconst_iterator(const InOutIter& current, 
147			       VALUE seq = Qnil)
148    {
149      return new SetIteratorOpen_T< InOutIter >(current, seq);
150    }
151
152  }
153%}
154
155
156%define %swig_set_methods(set...)
157
158  %swig_sequence_methods_common(%arg(set));
159
160  %fragment("RubyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool),fragment="RubySequence_Cont") {}
161
162// Redefine std::set iterator/reverse_iterator typemap
163%typemap(out,noblock=1) iterator, reverse_iterator {
164  $result = SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,const $type &),
165								self),
166			          swig::Iterator::descriptor(),SWIG_POINTER_OWN);
167 }
168
169// Redefine std::set std::pair<iterator, bool> typemap
170  %typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator")
171  std::pair<iterator, bool> {
172    $result = rb_ary_new2(2);
173    rb_ary_push($result, SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,$type &).first),
174                                            swig::Iterator::descriptor(),SWIG_POINTER_OWN));
175    rb_ary_push($result, SWIG_From(bool)(%static_cast($1,const $type &).second));
176   }
177
178  %extend  {
179    %alias push "<<";
180    value_type push(const value_type& x) {
181      self->insert(x);
182      return x;
183    }
184  
185    bool __contains__(const value_type& x) {
186      return self->find(x) != self->end();
187    }
188
189    value_type __getitem__(difference_type i) const throw (std::out_of_range) {
190      return *(swig::cgetpos(self, i));
191    }
192
193  };
194%enddef
195
196
197%mixin std::set "Enumerable";
198
199
200
201%rename("delete")     std::set::__delete__;
202%rename("reject!")    std::set::reject_bang;
203%rename("map!")       std::set::map_bang;
204%rename("empty?")     std::set::empty;
205%rename("include?" )  std::set::__contains__ const;
206%rename("has_key?" )  std::set::has_key const;
207
208%alias  std::set::push          "<<";
209
210
211%include <std/std_set.i>
212