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>") { 13 namespace 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") { 117 namespace 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"); 292 namespace 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 358