/* ----------------------------------------------------------------------------- * scicontainer.swg * * Scilab list <-> C++ container wrapper * * This wrapper, and its iterator, allows a general use (and reuse) of * the mapping between C++ and Scilab, thanks to the C++ templates. * * Of course, it needs the C++ compiler to support templates, but * since we will use this wrapper with the STL containers, that should * be the case. * ----------------------------------------------------------------------------- */ %{ #include %} #if !defined(SWIG_NO_EXPORT_ITERATOR_METHODS) # if !defined(SWIG_EXPORT_ITERATOR_METHODS) # define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS # endif #endif // #define (SWIG_SCILAB_EXTRA_NATIVE_CONTAINERS) // if defined: sequences in return are converted from/to Scilab lists or matrices // if not defined: sequences are passed from/to Scilab as pointers %{ #define SWIG_STD_NOASSIGN_STL %} %include %include %{ #include %} %include %include %fragment("SciSequence_Cont", "header", fragment="StdTraits", fragment="SwigSciIterator_T") { namespace swig { template struct SciSequence_Ref { SciSequence_Ref(const SwigSciObject& seq, int index) : _seq(seq), _index(index) { if (traits_as_sequence::get(_seq, &piSeqAddr) != SWIG_OK) { throw std::invalid_argument("Cannot get sequence data."); } } operator T () const { try { return traits_asval_sequenceitem::asval(_seq, piSeqAddr, _index); } catch (std::exception& e) { SWIG_exception(SWIG_RuntimeError, e.what()); } } SciSequence_Ref& operator=(const T& v) { // TODO return *this; } private: SwigSciObject _seq; int _index; void *piSeqAddr; }; template struct SciSequence_ArrowProxy { SciSequence_ArrowProxy(const T& x): m_value(x) {} const T* operator->() const { return &m_value; } operator const T*() const { return &m_value; } T m_value; }; template struct SwigSciSequence_InputIterator { typedef SwigSciSequence_InputIterator self; typedef std::random_access_iterator_tag iterator_category; typedef Reference reference; typedef T value_type; typedef T* pointer; typedef int difference_type; SwigSciSequence_InputIterator() { } SwigSciSequence_InputIterator(const SwigSciObject& seq, int index) : _seq(seq), _index(index) { } reference operator*() const { return reference(_seq, _index); } SciSequence_ArrowProxy operator->() const { return SciSequence_ArrowProxy(operator*()); } bool operator==(const self& ri) const { return (_index == ri._index); } bool operator!=(const self& ri) const { return !(operator==(ri)); } self& operator ++ () { ++_index; return *this; } self& operator -- () { --_index; return *this; } self& operator += (difference_type n) { _index += n; return *this; } self operator +(difference_type n) const { return self(_seq, _index + n); } self& operator -= (difference_type n) { _index -= n; return *this; } self operator -(difference_type n) const { return self(_seq, _index - n); } difference_type operator - (const self& ri) const { return _index - ri._index; } bool operator < (const self& ri) const { return _index < ri._index; } reference operator[](difference_type n) const { return reference(_seq, _index + n); } private: SwigSciObject _seq; difference_type _index; }; template struct SciSequence_Cont { typedef SciSequence_Ref reference; typedef const SciSequence_Ref const_reference; typedef T value_type; typedef T* pointer; typedef int difference_type; typedef int size_type; typedef const pointer const_pointer; typedef SwigSciSequence_InputIterator iterator; typedef SwigSciSequence_InputIterator const_iterator; SciSequence_Cont(const SwigSciObject& seq) : _seq(seq) { } ~SciSequence_Cont() { } size_type size() const { int iSeqSize; if (traits_as_sequence::size(_seq, &iSeqSize) == SWIG_OK) { return iSeqSize; } else { return SWIG_ERROR; } } bool empty() const { return size() == 0; } iterator begin() { return iterator(_seq, 0); } const_iterator begin() const { return const_iterator(_seq, 0); } iterator end() { return iterator(_seq, size()); } const_iterator end() const { return const_iterator(_seq, size()); } reference operator[](difference_type n) { return reference(_seq, n); } const_reference operator[](difference_type n) const { return const_reference(_seq, n); } private: SwigSciObject _seq; }; } } %define %swig_sequence_iterator(Sequence...) #if defined(SWIG_EXPORT_ITERATOR_METHODS) class iterator; class reverse_iterator; class const_iterator; class const_reverse_iterator; %typemap(out,noblock=1,fragment="SciSequence_Cont") iterator, reverse_iterator, const_iterator, const_reverse_iterator { %set_output(SWIG_NewPointerObj(swig::make_output_iterator(%static_cast($1,const $type &)), swig::SciSwigIterator::descriptor(),SWIG_POINTER_OWN)); } %typemap(out,fragment="SciSequence_Cont") std::pair, std::pair { // TODO: return a Scilab list from the pair (see code for Octave) } %fragment("SciSwigPairBoolOutputIterator", "header", fragment=SWIG_From_frag(bool), fragment="SciSequence_Cont") {} %typemap(out,fragment="SciSwigPairBoolOutputIterator") std::pair, std::pair { // TODO: return a Scilab list from the pair (see code for Octave) } %typemap(in,noblock=1,fragment="SciSequence_Cont") iterator(swig::SciSwigIterator *iter = 0, int res), reverse_iterator(swig::SciSwigIterator *iter = 0, int res), const_iterator(swig::SciSwigIterator *iter = 0, int res), const_reverse_iterator(swig::SciSwigIterator *iter = 0, int res) { res = SWIG_ConvertPtr((SwigSciObject)$input, %as_voidptrptr(&iter), swig::SciSwigIterator::descriptor(), 0); if (!SWIG_IsOK(res) || !iter) { %argument_fail(SWIG_TypeError, "$type", $symname, $argnum); } else { swig::SwigSciIterator_T<$type > *iter_t = dynamic_cast *>(iter); if (iter_t) { $1 = iter_t->get_current(); } else { %argument_fail(SWIG_TypeError, "$type", $symname, $argnum); } } } %typecheck(%checkcode(ITERATOR),noblock=1,fragment="SciSequence_Cont") iterator, reverse_iterator, const_iterator, const_reverse_iterator { swig::SciSwigIterator *iter = 0; int res = SWIG_ConvertPtr((SwigSciObject)$input, %as_voidptrptr(&iter), swig::SciSwigIterator::descriptor(), 0); $1 = (SWIG_IsOK(res) && iter && (dynamic_cast *>(iter) != 0)); } %fragment("SciSequence_Cont"); #endif //SWIG_EXPORT_ITERATOR_METHODS %enddef // The Scilab container methods %define %swig_container_methods(Container...) %enddef %define %swig_sequence_methods_common(Sequence...) %swig_sequence_iterator(%arg(Sequence)) %swig_container_methods(%arg(Sequence)) %enddef %define %swig_sequence_methods(Sequence...) %swig_sequence_methods_common(%arg(Sequence)) %enddef %define %swig_sequence_methods_val(Sequence...) %swig_sequence_methods_common(%arg(Sequence)) %enddef // // Common fragments // %fragment("StdSequenceTraits","header", fragment="StdTraits", fragment="SciSequence_Cont", fragment=SWIG_Traits_SequenceItem_frag(ptr)) { namespace swig { template inline void assign(const SciSeq& sciSeq, Seq* seq) { %#ifdef SWIG_STD_NOASSIGN_STL typedef typename SciSeq::value_type value_type; typename SciSeq::const_iterator it = sciSeq.begin(); for (;it != sciSeq.end(); ++it) { seq->insert(seq->end(),(value_type)(*it)); } %#else seq->assign(sciSeq.begin(), sciSeq.end()); %#endif } template struct traits_asptr_stdseq { typedef Seq sequence; typedef T value_type; static int asptr(const SwigSciObject& obj, sequence **seq) { swig_type_info *typeInfo = swig::type_info(); if (typeInfo) { sequence *p; if (SWIG_ConvertPtr(obj, (void**)&p, typeInfo, 0) == SWIG_OK) { if (seq) *seq = p; return SWIG_OLDOBJ; } } if (traits_as_sequence::check(obj) == SWIG_OK) { try { SciSequence_Cont sciSeq(obj); if (seq) { *seq = new sequence(); assign(sciSeq, *seq); return SWIG_NEWOBJ; } else { return true; } } catch (std::exception& e) { SWIG_exception(SWIG_RuntimeError, e.what()); } } } }; template struct traits_from_stdseq { typedef Seq sequence; typedef T value_type; typedef typename Seq::size_type size_type; typedef typename sequence::const_iterator const_iterator; static SwigSciObject from(const sequence& seq) { %#ifdef SWIG_SCILAB_EXTRA_NATIVE_CONTAINERS swig_type_info *typeInfo = swig::type_info(); if (typeInfo) { return SWIG_NewPointerObj(new sequence(seq), typeInfo, SWIG_POINTER_OWN); } %#endif try { void *data; size_type size = seq.size(); if (traits_from_sequence::create(size, &data) == SWIG_OK) { const_iterator it; int index = 0; for (it = seq.begin(); it != seq.end(); ++it) { traits_from_sequenceitem::from(data, index, *it); index++; } return traits_from_sequence::set(size, data); } return SWIG_OK; } catch (std::exception& e) { SWIG_exception(SWIG_RuntimeError, e.what()); } } }; } }