446 lines
11 KiB
Plaintext
446 lines
11 KiB
Plaintext
/* -----------------------------------------------------------------------------
|
|
* 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 <iostream>
|
|
%}
|
|
|
|
#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 <sciiterators.swg>
|
|
%include <scisequence.swg>
|
|
|
|
%{
|
|
#include <stdexcept>
|
|
%}
|
|
|
|
%include <exception.i>
|
|
%include <std_except.i>
|
|
|
|
%fragment("SciSequence_Cont", "header",
|
|
fragment="StdTraits",
|
|
fragment="SwigSciIterator_T",
|
|
fragment=SWIG_Traits_Sequence_frag(ptr),
|
|
fragment=SWIG_Traits_SequenceItem_frag(ptr))
|
|
{
|
|
namespace swig
|
|
{
|
|
template <class T>
|
|
struct SciSequence_Ref
|
|
{
|
|
SciSequence_Ref(const SwigSciObject& seq, int index)
|
|
: _seq(seq), _index(index)
|
|
{
|
|
if (traits_as_sequence<T>::get(_seq, &piSeqAddr) != SWIG_OK)
|
|
{
|
|
throw std::invalid_argument("Cannot get sequence data.");
|
|
}
|
|
}
|
|
|
|
operator T () const
|
|
{
|
|
return traits_asval_sequenceitem<T>::asval(_seq, piSeqAddr, _index);
|
|
}
|
|
|
|
SciSequence_Ref& operator=(const T& v)
|
|
{
|
|
// TODO
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
SwigSciObject _seq;
|
|
int _index;
|
|
void *piSeqAddr;
|
|
};
|
|
|
|
|
|
template <class T>
|
|
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 <class T, class Reference >
|
|
struct SwigSciSequence_InputIterator
|
|
{
|
|
typedef SwigSciSequence_InputIterator<T, Reference > 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<T>
|
|
operator->() const {
|
|
return SciSequence_ArrowProxy<T>(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 <class T>
|
|
struct SciSequence_Cont
|
|
{
|
|
typedef SciSequence_Ref<T> reference;
|
|
typedef const SciSequence_Ref<T> 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<T, reference> iterator;
|
|
typedef SwigSciSequence_InputIterator<T, const_reference> const_iterator;
|
|
|
|
SciSequence_Cont(const SwigSciObject& seq) : _seq(seq)
|
|
{
|
|
}
|
|
|
|
~SciSequence_Cont()
|
|
{
|
|
}
|
|
|
|
size_type size() const
|
|
{
|
|
int iSeqSize;
|
|
if (traits_as_sequence<value_type>::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<iterator, iterator>, std::pair<const_iterator, const_iterator> {
|
|
// 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<iterator, bool>, std::pair<const_iterator, bool> {
|
|
// 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<swig::SwigSciIterator_T<$type > *>(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<swig::SwigSciIterator_T<$type > *>(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")
|
|
{
|
|
namespace swig {
|
|
template <class SciSeq, class Seq>
|
|
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 <class Seq, class T = typename Seq::value_type >
|
|
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<sequence>();
|
|
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<value_type>::check(obj) == SWIG_OK)
|
|
{
|
|
try
|
|
{
|
|
SciSequence_Cont<value_type> sciSeq(obj);
|
|
if (seq)
|
|
{
|
|
*seq = new sequence();
|
|
assign(sciSeq, *seq);
|
|
return SWIG_NEWOBJ;
|
|
}
|
|
else
|
|
{
|
|
return SWIG_ERROR;
|
|
}
|
|
}
|
|
catch (std::exception& e)
|
|
{
|
|
SWIG_exception(SWIG_RuntimeError, e.what());
|
|
return SWIG_ERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return SWIG_ERROR;
|
|
}
|
|
}
|
|
};
|
|
|
|
template <class Seq, class T = typename Seq::value_type >
|
|
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<sequence>();
|
|
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<value_type>::create(size, &data) == SWIG_OK) {
|
|
const_iterator it;
|
|
int index = 0;
|
|
for (it = seq.begin(); it != seq.end(); ++it)
|
|
{
|
|
traits_from_sequenceitem<value_type>::from(data, index, *it);
|
|
index++;
|
|
}
|
|
return traits_from_sequence<value_type>::set(size, data);
|
|
}
|
|
return SWIG_OK;
|
|
}
|
|
catch (std::exception& e)
|
|
{
|
|
SWIG_exception(SWIG_RuntimeError, e.what());
|
|
return SWIG_ERROR;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
}
|