scicontainer.swg 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /* -----------------------------------------------------------------------------
  2. * scicontainer.swg
  3. *
  4. * Scilab list <-> C++ container wrapper
  5. *
  6. * This wrapper, and its iterator, allows a general use (and reuse) of
  7. * the mapping between C++ and Scilab, thanks to the C++ templates.
  8. *
  9. * Of course, it needs the C++ compiler to support templates, but
  10. * since we will use this wrapper with the STL containers, that should
  11. * be the case.
  12. * ----------------------------------------------------------------------------- */
  13. %{
  14. #include <iostream>
  15. %}
  16. #if !defined(SWIG_NO_EXPORT_ITERATOR_METHODS)
  17. # if !defined(SWIG_EXPORT_ITERATOR_METHODS)
  18. # define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS
  19. # endif
  20. #endif
  21. // #define (SWIG_SCILAB_EXTRA_NATIVE_CONTAINERS)
  22. // if defined: sequences in return are converted from/to Scilab lists or matrices
  23. // if not defined: sequences are passed from/to Scilab as pointers
  24. %{
  25. #define SWIG_STD_NOASSIGN_STL
  26. %}
  27. %include <sciiterators.swg>
  28. %include <scisequence.swg>
  29. %{
  30. #include <stdexcept>
  31. %}
  32. %include <exception.i>
  33. %include <std_except.i>
  34. %fragment("SciSequence_Cont", "header",
  35. fragment="StdTraits",
  36. fragment="SwigSciIterator_T")
  37. {
  38. namespace swig
  39. {
  40. template <class T>
  41. struct SciSequence_Ref
  42. {
  43. SciSequence_Ref(const SwigSciObject& seq, int index)
  44. : _seq(seq), _index(index)
  45. {
  46. if (traits_as_sequence<T>::get(_seq, &piSeqAddr) != SWIG_OK)
  47. {
  48. throw std::invalid_argument("Cannot get sequence data.");
  49. }
  50. }
  51. operator T () const
  52. {
  53. try
  54. {
  55. return traits_asval_sequenceitem<T>::asval(_seq, piSeqAddr, _index);
  56. }
  57. catch (std::exception& e)
  58. {
  59. SWIG_exception(SWIG_RuntimeError, e.what());
  60. }
  61. }
  62. SciSequence_Ref& operator=(const T& v)
  63. {
  64. // TODO
  65. return *this;
  66. }
  67. private:
  68. SwigSciObject _seq;
  69. int _index;
  70. void *piSeqAddr;
  71. };
  72. template <class T>
  73. struct SciSequence_ArrowProxy
  74. {
  75. SciSequence_ArrowProxy(const T& x): m_value(x) {}
  76. const T* operator->() const { return &m_value; }
  77. operator const T*() const { return &m_value; }
  78. T m_value;
  79. };
  80. template <class T, class Reference >
  81. struct SwigSciSequence_InputIterator
  82. {
  83. typedef SwigSciSequence_InputIterator<T, Reference > self;
  84. typedef std::random_access_iterator_tag iterator_category;
  85. typedef Reference reference;
  86. typedef T value_type;
  87. typedef T* pointer;
  88. typedef int difference_type;
  89. SwigSciSequence_InputIterator()
  90. {
  91. }
  92. SwigSciSequence_InputIterator(const SwigSciObject& seq, int index)
  93. : _seq(seq), _index(index)
  94. {
  95. }
  96. reference operator*() const
  97. {
  98. return reference(_seq, _index);
  99. }
  100. SciSequence_ArrowProxy<T>
  101. operator->() const {
  102. return SciSequence_ArrowProxy<T>(operator*());
  103. }
  104. bool operator==(const self& ri) const
  105. {
  106. return (_index == ri._index);
  107. }
  108. bool operator!=(const self& ri) const
  109. {
  110. return !(operator==(ri));
  111. }
  112. self& operator ++ ()
  113. {
  114. ++_index;
  115. return *this;
  116. }
  117. self& operator -- ()
  118. {
  119. --_index;
  120. return *this;
  121. }
  122. self& operator += (difference_type n)
  123. {
  124. _index += n;
  125. return *this;
  126. }
  127. self operator +(difference_type n) const
  128. {
  129. return self(_seq, _index + n);
  130. }
  131. self& operator -= (difference_type n)
  132. {
  133. _index -= n;
  134. return *this;
  135. }
  136. self operator -(difference_type n) const
  137. {
  138. return self(_seq, _index - n);
  139. }
  140. difference_type operator - (const self& ri) const
  141. {
  142. return _index - ri._index;
  143. }
  144. bool operator < (const self& ri) const
  145. {
  146. return _index < ri._index;
  147. }
  148. reference
  149. operator[](difference_type n) const
  150. {
  151. return reference(_seq, _index + n);
  152. }
  153. private:
  154. SwigSciObject _seq;
  155. difference_type _index;
  156. };
  157. template <class T>
  158. struct SciSequence_Cont
  159. {
  160. typedef SciSequence_Ref<T> reference;
  161. typedef const SciSequence_Ref<T> const_reference;
  162. typedef T value_type;
  163. typedef T* pointer;
  164. typedef int difference_type;
  165. typedef int size_type;
  166. typedef const pointer const_pointer;
  167. typedef SwigSciSequence_InputIterator<T, reference> iterator;
  168. typedef SwigSciSequence_InputIterator<T, const_reference> const_iterator;
  169. SciSequence_Cont(const SwigSciObject& seq) : _seq(seq)
  170. {
  171. }
  172. ~SciSequence_Cont()
  173. {
  174. }
  175. size_type size() const
  176. {
  177. int iSeqSize;
  178. if (traits_as_sequence<value_type>::size(_seq, &iSeqSize) == SWIG_OK)
  179. {
  180. return iSeqSize;
  181. }
  182. else
  183. {
  184. return SWIG_ERROR;
  185. }
  186. }
  187. bool empty() const
  188. {
  189. return size() == 0;
  190. }
  191. iterator begin()
  192. {
  193. return iterator(_seq, 0);
  194. }
  195. const_iterator begin() const
  196. {
  197. return const_iterator(_seq, 0);
  198. }
  199. iterator end()
  200. {
  201. return iterator(_seq, size());
  202. }
  203. const_iterator end() const
  204. {
  205. return const_iterator(_seq, size());
  206. }
  207. reference operator[](difference_type n)
  208. {
  209. return reference(_seq, n);
  210. }
  211. const_reference operator[](difference_type n) const
  212. {
  213. return const_reference(_seq, n);
  214. }
  215. private:
  216. SwigSciObject _seq;
  217. };
  218. }
  219. }
  220. %define %swig_sequence_iterator(Sequence...)
  221. #if defined(SWIG_EXPORT_ITERATOR_METHODS)
  222. class iterator;
  223. class reverse_iterator;
  224. class const_iterator;
  225. class const_reverse_iterator;
  226. %typemap(out,noblock=1,fragment="SciSequence_Cont")
  227. iterator, reverse_iterator, const_iterator, const_reverse_iterator {
  228. %set_output(SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &)),
  229. swig::SciSwigIterator::descriptor(),SWIG_POINTER_OWN));
  230. }
  231. %typemap(out,fragment="SciSequence_Cont")
  232. std::pair<iterator, iterator>, std::pair<const_iterator, const_iterator> {
  233. // TODO: return a Scilab list from the pair (see code for Octave)
  234. }
  235. %fragment("SciSwigPairBoolOutputIterator", "header",
  236. fragment=SWIG_From_frag(bool), fragment="SciSequence_Cont") {}
  237. %typemap(out,fragment="SciSwigPairBoolOutputIterator")
  238. std::pair<iterator, bool>, std::pair<const_iterator, bool> {
  239. // TODO: return a Scilab list from the pair (see code for Octave)
  240. }
  241. %typemap(in,noblock=1,fragment="SciSequence_Cont")
  242. iterator(swig::SciSwigIterator *iter = 0, int res),
  243. reverse_iterator(swig::SciSwigIterator *iter = 0, int res),
  244. const_iterator(swig::SciSwigIterator *iter = 0, int res),
  245. const_reverse_iterator(swig::SciSwigIterator *iter = 0, int res) {
  246. res = SWIG_ConvertPtr((SwigSciObject)$input, %as_voidptrptr(&iter), swig::SciSwigIterator::descriptor(), 0);
  247. if (!SWIG_IsOK(res) || !iter) {
  248. %argument_fail(SWIG_TypeError, "$type", $symname, $argnum);
  249. } else {
  250. swig::SwigSciIterator_T<$type > *iter_t = dynamic_cast<swig::SwigSciIterator_T<$type > *>(iter);
  251. if (iter_t) {
  252. $1 = iter_t->get_current();
  253. } else {
  254. %argument_fail(SWIG_TypeError, "$type", $symname, $argnum);
  255. }
  256. }
  257. }
  258. %typecheck(%checkcode(ITERATOR),noblock=1,fragment="SciSequence_Cont")
  259. iterator, reverse_iterator, const_iterator, const_reverse_iterator {
  260. swig::SciSwigIterator *iter = 0;
  261. int res = SWIG_ConvertPtr((SwigSciObject)$input, %as_voidptrptr(&iter), swig::SciSwigIterator::descriptor(), 0);
  262. $1 = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigSciIterator_T<$type > *>(iter) != 0));
  263. }
  264. %fragment("SciSequence_Cont");
  265. #endif //SWIG_EXPORT_ITERATOR_METHODS
  266. %enddef
  267. // The Scilab container methods
  268. %define %swig_container_methods(Container...)
  269. %enddef
  270. %define %swig_sequence_methods_common(Sequence...)
  271. %swig_sequence_iterator(%arg(Sequence))
  272. %swig_container_methods(%arg(Sequence))
  273. %enddef
  274. %define %swig_sequence_methods(Sequence...)
  275. %swig_sequence_methods_common(%arg(Sequence))
  276. %enddef
  277. %define %swig_sequence_methods_val(Sequence...)
  278. %swig_sequence_methods_common(%arg(Sequence))
  279. %enddef
  280. //
  281. // Common fragments
  282. //
  283. %fragment("StdSequenceTraits","header",
  284. fragment="StdTraits",
  285. fragment="SciSequence_Cont",
  286. fragment=SWIG_Traits_SequenceItem_frag(ptr))
  287. {
  288. namespace swig {
  289. template <class SciSeq, class Seq>
  290. inline void
  291. assign(const SciSeq& sciSeq, Seq* seq) {
  292. %#ifdef SWIG_STD_NOASSIGN_STL
  293. typedef typename SciSeq::value_type value_type;
  294. typename SciSeq::const_iterator it = sciSeq.begin();
  295. for (;it != sciSeq.end(); ++it) {
  296. seq->insert(seq->end(),(value_type)(*it));
  297. }
  298. %#else
  299. seq->assign(sciSeq.begin(), sciSeq.end());
  300. %#endif
  301. }
  302. template <class Seq, class T = typename Seq::value_type >
  303. struct traits_asptr_stdseq {
  304. typedef Seq sequence;
  305. typedef T value_type;
  306. static int asptr(const SwigSciObject& obj, sequence **seq)
  307. {
  308. swig_type_info *typeInfo = swig::type_info<sequence>();
  309. if (typeInfo)
  310. {
  311. sequence *p;
  312. if (SWIG_ConvertPtr(obj, (void**)&p, typeInfo, 0) == SWIG_OK)
  313. {
  314. if (seq)
  315. *seq = p;
  316. return SWIG_OLDOBJ;
  317. }
  318. }
  319. if (traits_as_sequence<value_type>::check(obj) == SWIG_OK)
  320. {
  321. try
  322. {
  323. SciSequence_Cont<value_type> sciSeq(obj);
  324. if (seq)
  325. {
  326. *seq = new sequence();
  327. assign(sciSeq, *seq);
  328. return SWIG_NEWOBJ;
  329. }
  330. else
  331. {
  332. return true;
  333. }
  334. }
  335. catch (std::exception& e)
  336. {
  337. SWIG_exception(SWIG_RuntimeError, e.what());
  338. }
  339. }
  340. }
  341. };
  342. template <class Seq, class T = typename Seq::value_type >
  343. struct traits_from_stdseq {
  344. typedef Seq sequence;
  345. typedef T value_type;
  346. typedef typename Seq::size_type size_type;
  347. typedef typename sequence::const_iterator const_iterator;
  348. static SwigSciObject from(const sequence& seq)
  349. {
  350. %#ifdef SWIG_SCILAB_EXTRA_NATIVE_CONTAINERS
  351. swig_type_info *typeInfo = swig::type_info<sequence>();
  352. if (typeInfo)
  353. {
  354. return SWIG_NewPointerObj(new sequence(seq), typeInfo, SWIG_POINTER_OWN);
  355. }
  356. %#endif
  357. try
  358. {
  359. void *data;
  360. size_type size = seq.size();
  361. if (traits_from_sequence<value_type>::create(size, &data) == SWIG_OK) {
  362. const_iterator it;
  363. int index = 0;
  364. for (it = seq.begin(); it != seq.end(); ++it)
  365. {
  366. traits_from_sequenceitem<value_type>::from(data, index, *it);
  367. index++;
  368. }
  369. return traits_from_sequence<value_type>::set(size, data);
  370. }
  371. return SWIG_OK;
  372. }
  373. catch (std::exception& e)
  374. {
  375. SWIG_exception(SWIG_RuntimeError, e.what());
  376. }
  377. }
  378. };
  379. }
  380. }