PageRenderTime 10ms CodeModel.GetById 1ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Lib/octave/octiterators.swg

#
Unknown | 357 lines | 294 code | 63 blank | 0 comment | 0 complexity | 1444632bfef3ef3354453c19650eefc9 MD5 | raw file
  1/* -----------------------------------------------------------------------------
  2 * octiterators.swg
  3 *
  4 * Users can derive form the OctSwigIterator to implemet their
  5 * own iterators. As an example (real one since we use it for STL/STD
  6 * containers), the template OctSwigIterator_T does the
  7 * implementation for generic C++ iterators.
  8 * ----------------------------------------------------------------------------- */
  9
 10%include <std_common.i>
 11
 12%fragment("OctSwigIterator","header",fragment="<stddef.h>") {  
 13namespace swig {
 14  struct stop_iteration {
 15  };
 16
 17  struct OctSwigIterator {
 18  private:
 19    octave_value _seq;
 20
 21  protected:
 22    OctSwigIterator(octave_value seq) : _seq(seq)
 23    {
 24    }
 25      
 26  public:
 27    virtual ~OctSwigIterator() {}
 28
 29    virtual octave_value value() const = 0;
 30
 31    virtual OctSwigIterator *incr(size_t n = 1) = 0;
 32
 33    virtual OctSwigIterator *decr(size_t n = 1)
 34    {
 35      throw stop_iteration();
 36    }
 37
 38    virtual ptrdiff_t distance(const OctSwigIterator &x) const
 39    {
 40      throw std::invalid_argument("operation not supported");
 41    }
 42
 43    virtual bool equal (const OctSwigIterator &x) const
 44    {
 45      throw std::invalid_argument("operation not supported");
 46    }
 47    
 48    virtual OctSwigIterator *copy() const = 0;
 49
 50    octave_value next()
 51    {
 52      octave_value obj = value();
 53      incr();
 54      return obj;
 55    }
 56
 57    octave_value previous()
 58    {
 59      decr();
 60      return value();
 61    }
 62
 63    OctSwigIterator *advance(ptrdiff_t n)
 64    {
 65      return  (n > 0) ?  incr(n) : decr(-n);
 66    }
 67      
 68    bool operator == (const OctSwigIterator& x)  const
 69    {
 70      return equal(x);
 71    }
 72      
 73    bool operator != (const OctSwigIterator& x) const
 74    {
 75      return ! operator==(x);
 76    }
 77
 78    OctSwigIterator* operator ++ () {
 79      incr();
 80      return this;
 81    }
 82
 83    OctSwigIterator* operator -- () {
 84      decr();
 85      return this;
 86    }
 87      
 88    OctSwigIterator* operator + (ptrdiff_t n) const
 89    {
 90      return copy()->advance(n);
 91    }
 92
 93    OctSwigIterator* operator - (ptrdiff_t n) const
 94    {
 95      return copy()->advance(-n);
 96    }
 97      
 98    ptrdiff_t operator - (const OctSwigIterator& x) const
 99    {
100      return x.distance(*this);
101    }
102      
103    static swig_type_info* descriptor() {
104      static int init = 0;
105      static swig_type_info* desc = 0;
106      if (!init) {
107	desc = SWIG_TypeQuery("swig::OctSwigIterator *");
108	init = 1;
109      }	
110      return desc;
111    }    
112  };
113}
114}
115
116%fragment("OctSwigIterator_T","header",fragment="<stddef.h>",fragment="OctSwigIterator",fragment="StdTraits",fragment="StdIteratorTraits") {
117namespace swig {
118  template<typename OutIterator>
119  class OctSwigIterator_T :  public OctSwigIterator
120  {
121  public:
122    typedef OutIterator out_iterator;
123    typedef typename std::iterator_traits<out_iterator>::value_type value_type;    
124    typedef OctSwigIterator_T<out_iterator> self_type;
125
126    OctSwigIterator_T(out_iterator curr, octave_value seq)
127      : OctSwigIterator(seq), current(curr)
128    {
129    }
130
131    const out_iterator& get_current() const
132    {
133      return current;
134    }
135
136    
137    bool equal (const OctSwigIterator &iter) const
138    {
139      const self_type *iters = dynamic_cast<const self_type *>(&iter);
140      if (iters) {
141	return (current == iters->get_current());
142      } else {
143	throw std::invalid_argument("bad iterator type");
144      }
145    }
146    
147    ptrdiff_t distance(const OctSwigIterator &iter) const
148    {
149      const self_type *iters = dynamic_cast<const self_type *>(&iter);
150      if (iters) {
151	return std::distance(current, iters->get_current());
152      } else {
153	throw std::invalid_argument("bad iterator type");
154      }
155    }    
156    
157  protected:
158    out_iterator current;
159  };
160  
161  template <class ValueType>
162  struct from_oper 
163  {
164    typedef const ValueType& argument_type;
165    typedef octave_value result_type;
166    result_type operator()(argument_type v) const
167    {
168      return swig::from(v);
169    }
170  };
171
172  template<typename OutIterator, 
173	   typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
174	   typename FromOper = from_oper<ValueType> >
175  class OctSwigIteratorOpen_T :  public OctSwigIterator_T<OutIterator>
176  {
177  public:
178    FromOper from;
179    typedef OutIterator out_iterator;
180    typedef ValueType value_type;
181    typedef OctSwigIterator_T<out_iterator>  base;
182    typedef OctSwigIteratorOpen_T<OutIterator, ValueType, FromOper> self_type;
183    
184    OctSwigIteratorOpen_T(out_iterator curr, octave_value seq)
185      : OctSwigIterator_T<OutIterator>(curr, seq)
186    {
187    }
188    
189    octave_value value() const {
190      return from(static_cast<const value_type&>(*(base::current)));
191    }
192    
193    OctSwigIterator *copy() const
194    {
195      return new self_type(*this);
196    }
197
198    OctSwigIterator *incr(size_t n = 1)
199    {
200      while (n--) {
201	++base::current;
202      }
203      return this;
204    }
205
206    OctSwigIterator *decr(size_t n = 1)
207    {
208      while (n--) {
209	--base::current;
210      }
211      return this;
212    }
213  };
214
215  template<typename OutIterator, 
216	   typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
217	   typename FromOper = from_oper<ValueType> >
218  class OctSwigIteratorClosed_T :  public OctSwigIterator_T<OutIterator>
219  {
220  public:
221    FromOper from;
222    typedef OutIterator out_iterator;
223    typedef ValueType value_type;
224    typedef OctSwigIterator_T<out_iterator>  base;    
225    typedef OctSwigIteratorClosed_T<OutIterator, ValueType, FromOper> self_type;
226    
227    OctSwigIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, octave_value seq)
228      : OctSwigIterator_T<OutIterator>(curr, seq), begin(first), end(last)
229    {
230    }
231    
232    octave_value value() const {
233      if (base::current == end) {
234	throw stop_iteration();
235      } else {
236	return from(static_cast<const value_type&>(*(base::current)));
237      }
238    }
239    
240    OctSwigIterator *copy() const
241    {
242      return new self_type(*this);
243    }
244
245    OctSwigIterator *incr(size_t n = 1)
246    {
247      while (n--) {
248	if (base::current == end) {
249	  throw stop_iteration();
250	} else {
251	  ++base::current;
252	}
253      }
254      return this;
255    }
256
257    OctSwigIterator *decr(size_t n = 1)
258    {
259      while (n--) {
260	if (base::current == begin) {
261	  throw stop_iteration();
262	} else {
263	  --base::current;
264	}
265      }
266      return this;
267    }
268
269  private:
270    out_iterator begin;
271    out_iterator end;
272  };
273
274  template<typename OutIter>
275  inline OctSwigIterator*
276  make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, octave_value seq = octave_value())
277  {
278    return new OctSwigIteratorClosed_T<OutIter>(current, begin, end, seq);
279  }
280
281  template<typename OutIter>
282  inline OctSwigIterator*
283  make_output_iterator(const OutIter& current, octave_value seq = octave_value())
284  {
285    return new OctSwigIteratorOpen_T<OutIter>(current, seq);
286  }
287}
288}
289
290
291%fragment("OctSwigIterator");
292namespace swig 
293{
294// Throw a StopIteration exception
295  %ignore stop_iteration;
296  struct stop_iteration {};
297  
298  %typemap(throws) stop_iteration {
299    error("stop_iteration exception");
300    SWIG_fail;
301  }
302
303// Mark methods that return new objects
304  %newobject OctSwigIterator::copy;
305  %newobject OctSwigIterator::operator + (ptrdiff_t n) const;
306  %newobject OctSwigIterator::operator - (ptrdiff_t n) const;
307
308  %nodirector OctSwigIterator;
309
310  %catches(swig::stop_iteration) OctSwigIterator::value() const;
311  %catches(swig::stop_iteration) OctSwigIterator::incr(size_t n = 1);
312  %catches(swig::stop_iteration) OctSwigIterator::decr(size_t n = 1);
313  %catches(std::invalid_argument) OctSwigIterator::distance(const OctSwigIterator &x) const;
314  %catches(std::invalid_argument) OctSwigIterator::equal (const OctSwigIterator &x) const;
315  %catches(swig::stop_iteration) OctSwigIterator::next();
316  %catches(swig::stop_iteration) OctSwigIterator::previous();
317  %catches(swig::stop_iteration) OctSwigIterator::advance(ptrdiff_t n);
318  %catches(swig::stop_iteration) OctSwigIterator::operator += (ptrdiff_t n);
319  %catches(swig::stop_iteration) OctSwigIterator::operator -= (ptrdiff_t n);
320  %catches(swig::stop_iteration) OctSwigIterator::operator + (ptrdiff_t n) const;
321  %catches(swig::stop_iteration) OctSwigIterator::operator - (ptrdiff_t n) const;
322
323
324  struct OctSwigIterator
325  {
326  protected:
327    OctSwigIterator(octave_value seq);
328
329  public:
330    virtual ~OctSwigIterator();
331
332    virtual octave_value value() const = 0;
333
334    virtual OctSwigIterator *incr(size_t n = 1) = 0;
335    
336    virtual OctSwigIterator *decr(size_t n = 1);
337
338    virtual ptrdiff_t distance(const OctSwigIterator &x) const;
339
340    virtual bool equal (const OctSwigIterator &x) const;
341    
342    virtual OctSwigIterator *copy() const = 0;
343
344    octave_value next();
345    octave_value previous();
346    OctSwigIterator *advance(ptrdiff_t n);
347
348    bool operator == (const OctSwigIterator& x)  const;
349    bool operator != (const OctSwigIterator& x) const;
350    OctSwigIterator* operator ++ ();
351    OctSwigIterator* operator -- ();
352    OctSwigIterator* operator + (ptrdiff_t n) const;
353    OctSwigIterator* operator - (ptrdiff_t n) const;
354    ptrdiff_t operator - (const OctSwigIterator& x) const;
355  };
356}
357