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