Files
baldurk 768e812e45 Commit binary dependencies necessary for compilation on windows
* On windows it's strongly desired to be able to compile straight out of
  a clean checkout or source download. This means anyone can download
  the source and investigate something quickly, without having to worry
  about the hassle of figuring out how the project downloads 3rd party
  dependencies, fetching them, getting them registered in the right
  place.
* This can't be put in a submodule as git submodules don't get
  downloaded by default so people new to git will get confusing
  compilation messages, and someone downloading the source from github
  directly without cloning via git won't get submodules included.
* It does add some extra size to a fresh download/checkout which is
  unfortunate, but absolutely worth the cost. Shallow checkouts still
  aren't unfeasibly large, and it's only a one-off cost at clone time.
2018-02-02 20:49:35 +00:00

406 lines
10 KiB
Plaintext

/* -----------------------------------------------------------------------------
* pyiterators.swg
*
* Implement a python 'output' iterator for Python 2.2 or higher.
*
* Users can derive form the SwigPyIterator to implement their
* own iterators. As an example (real one since we use it for STL/STD
* containers), the template SwigPyIterator_T does the
* implementation for generic C++ iterators.
* ----------------------------------------------------------------------------- */
%include <std_common.i>
%fragment("SwigPyIterator","header",fragment="<stddef.h>") {
namespace swig {
struct stop_iteration {
};
struct SwigPyIterator {
private:
SwigPtr_PyObject _seq;
protected:
SwigPyIterator(PyObject *seq) : _seq(seq)
{
}
public:
virtual ~SwigPyIterator() {}
// Access iterator method, required by Python
virtual PyObject *value() const = 0;
// Forward iterator method, required by Python
virtual SwigPyIterator *incr(size_t n = 1) = 0;
// Backward iterator method, very common in C++, but not required in Python
virtual SwigPyIterator *decr(size_t /*n*/ = 1)
{
throw stop_iteration();
}
// Random access iterator methods, but not required in Python
virtual ptrdiff_t distance(const SwigPyIterator &/*x*/) const
{
throw std::invalid_argument("operation not supported");
}
virtual bool equal (const SwigPyIterator &/*x*/) const
{
throw std::invalid_argument("operation not supported");
}
// C++ common/needed methods
virtual SwigPyIterator *copy() const = 0;
PyObject *next()
{
SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads
PyObject *obj = value();
incr();
SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads
return obj;
}
/* Make an alias for Python 3.x */
PyObject *__next__()
{
return next();
}
PyObject *previous()
{
SWIG_PYTHON_THREAD_BEGIN_BLOCK; // disable threads
decr();
PyObject *obj = value();
SWIG_PYTHON_THREAD_END_BLOCK; // re-enable threads
return obj;
}
SwigPyIterator *advance(ptrdiff_t n)
{
return (n > 0) ? incr(n) : decr(-n);
}
bool operator == (const SwigPyIterator& x) const
{
return equal(x);
}
bool operator != (const SwigPyIterator& x) const
{
return ! operator==(x);
}
SwigPyIterator& operator += (ptrdiff_t n)
{
return *advance(n);
}
SwigPyIterator& operator -= (ptrdiff_t n)
{
return *advance(-n);
}
SwigPyIterator* operator + (ptrdiff_t n) const
{
return copy()->advance(n);
}
SwigPyIterator* operator - (ptrdiff_t n) const
{
return copy()->advance(-n);
}
ptrdiff_t operator - (const SwigPyIterator& x) const
{
return x.distance(*this);
}
static swig_type_info* descriptor() {
static int init = 0;
static swig_type_info* desc = 0;
if (!init) {
desc = SWIG_TypeQuery("swig::SwigPyIterator *");
init = 1;
}
return desc;
}
};
%#if defined(SWIGPYTHON_BUILTIN)
inline PyObject* make_output_iterator_builtin (PyObject *pyself)
{
Py_INCREF(pyself);
return pyself;
}
%#endif
}
}
%fragment("SwigPyIterator_T","header",fragment="<stddef.h>",fragment="SwigPyIterator",fragment="StdTraits",fragment="StdIteratorTraits") {
namespace swig {
template<typename OutIterator>
class SwigPyIterator_T : public SwigPyIterator
{
public:
typedef OutIterator out_iterator;
typedef typename std::iterator_traits<out_iterator>::value_type value_type;
typedef SwigPyIterator_T<out_iterator> self_type;
SwigPyIterator_T(out_iterator curr, PyObject *seq)
: SwigPyIterator(seq), current(curr)
{
}
const out_iterator& get_current() const
{
return current;
}
bool equal (const SwigPyIterator &iter) const
{
const self_type *iters = dynamic_cast<const self_type *>(&iter);
if (iters) {
return (current == iters->get_current());
} else {
throw std::invalid_argument("bad iterator type");
}
}
ptrdiff_t distance(const SwigPyIterator &iter) const
{
const self_type *iters = dynamic_cast<const self_type *>(&iter);
if (iters) {
return std::distance(current, iters->get_current());
} else {
throw std::invalid_argument("bad iterator type");
}
}
protected:
out_iterator current;
};
template <class ValueType>
struct from_oper
{
typedef const ValueType& argument_type;
typedef PyObject *result_type;
result_type operator()(argument_type v) const
{
return swig::from(v);
}
};
template<typename OutIterator,
typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
typename FromOper = from_oper<ValueType> >
class SwigPyIteratorOpen_T : public SwigPyIterator_T<OutIterator>
{
public:
FromOper from;
typedef OutIterator out_iterator;
typedef ValueType value_type;
typedef SwigPyIterator_T<out_iterator> base;
typedef SwigPyIteratorOpen_T<OutIterator, ValueType, FromOper> self_type;
SwigPyIteratorOpen_T(out_iterator curr, PyObject *seq)
: SwigPyIterator_T<OutIterator>(curr, seq)
{
}
PyObject *value() const {
return from(static_cast<const value_type&>(*(base::current)));
}
SwigPyIterator *copy() const
{
return new self_type(*this);
}
SwigPyIterator *incr(size_t n = 1)
{
while (n--) {
++base::current;
}
return this;
}
SwigPyIterator *decr(size_t n = 1)
{
while (n--) {
--base::current;
}
return this;
}
};
template<typename OutIterator,
typename ValueType = typename std::iterator_traits<OutIterator>::value_type,
typename FromOper = from_oper<ValueType> >
class SwigPyIteratorClosed_T : public SwigPyIterator_T<OutIterator>
{
public:
FromOper from;
typedef OutIterator out_iterator;
typedef ValueType value_type;
typedef SwigPyIterator_T<out_iterator> base;
typedef SwigPyIteratorClosed_T<OutIterator, ValueType, FromOper> self_type;
SwigPyIteratorClosed_T(out_iterator curr, out_iterator first, out_iterator last, PyObject *seq)
: SwigPyIterator_T<OutIterator>(curr, seq), begin(first), end(last)
{
}
PyObject *value() const {
if (base::current == end) {
throw stop_iteration();
} else {
return from(static_cast<const value_type&>(*(base::current)));
}
}
SwigPyIterator *copy() const
{
return new self_type(*this);
}
SwigPyIterator *incr(size_t n = 1)
{
while (n--) {
if (base::current == end) {
throw stop_iteration();
} else {
++base::current;
}
}
return this;
}
SwigPyIterator *decr(size_t n = 1)
{
while (n--) {
if (base::current == begin) {
throw stop_iteration();
} else {
--base::current;
}
}
return this;
}
private:
out_iterator begin;
out_iterator end;
};
template<typename OutIter>
inline SwigPyIterator*
make_output_iterator(const OutIter& current, const OutIter& begin,const OutIter& end, PyObject *seq = 0)
{
return new SwigPyIteratorClosed_T<OutIter>(current, begin, end, seq);
}
template<typename OutIter>
inline SwigPyIterator*
make_output_iterator(const OutIter& current, PyObject *seq = 0)
{
return new SwigPyIteratorOpen_T<OutIter>(current, seq);
}
}
}
%fragment("SwigPyIterator");
namespace swig
{
/*
Throw a StopIteration exception
*/
%ignore stop_iteration;
struct stop_iteration {};
%typemap(throws) stop_iteration {
(void)$1;
SWIG_SetErrorObj(PyExc_StopIteration, SWIG_Py_Void());
SWIG_fail;
}
/*
Mark methods that return new objects
*/
%newobject SwigPyIterator::copy;
%newobject SwigPyIterator::operator + (ptrdiff_t n) const;
%newobject SwigPyIterator::operator - (ptrdiff_t n) const;
%nodirector SwigPyIterator;
#if defined(SWIGPYTHON_BUILTIN)
%feature("python:tp_iter") SwigPyIterator "&swig::make_output_iterator_builtin";
%feature("python:slot", "tp_iternext", functype="iternextfunc") SwigPyIterator::__next__;
#else
%extend SwigPyIterator {
%pythoncode %{def __iter__(self):
return self%}
}
#endif
%catches(swig::stop_iteration) SwigPyIterator::value() const;
%catches(swig::stop_iteration) SwigPyIterator::incr(size_t n = 1);
%catches(swig::stop_iteration) SwigPyIterator::decr(size_t n = 1);
%catches(std::invalid_argument) SwigPyIterator::distance(const SwigPyIterator &x) const;
%catches(std::invalid_argument) SwigPyIterator::equal (const SwigPyIterator &x) const;
%catches(swig::stop_iteration) SwigPyIterator::__next__();
%catches(swig::stop_iteration) SwigPyIterator::next();
%catches(swig::stop_iteration) SwigPyIterator::previous();
%catches(swig::stop_iteration) SwigPyIterator::advance(ptrdiff_t n);
%catches(swig::stop_iteration) SwigPyIterator::operator += (ptrdiff_t n);
%catches(swig::stop_iteration) SwigPyIterator::operator -= (ptrdiff_t n);
%catches(swig::stop_iteration) SwigPyIterator::operator + (ptrdiff_t n) const;
%catches(swig::stop_iteration) SwigPyIterator::operator - (ptrdiff_t n) const;
struct SwigPyIterator
{
protected:
SwigPyIterator(PyObject *seq);
public:
virtual ~SwigPyIterator();
// Access iterator method, required by Python
virtual PyObject *value() const = 0;
// Forward iterator method, required by Python
virtual SwigPyIterator *incr(size_t n = 1) = 0;
// Backward iterator method, very common in C++, but not required in Python
virtual SwigPyIterator *decr(size_t n = 1);
// Random access iterator methods, but not required in Python
virtual ptrdiff_t distance(const SwigPyIterator &x) const;
virtual bool equal (const SwigPyIterator &x) const;
// C++ common/needed methods
virtual SwigPyIterator *copy() const = 0;
PyObject *next();
PyObject *__next__();
PyObject *previous();
SwigPyIterator *advance(ptrdiff_t n);
bool operator == (const SwigPyIterator& x) const;
bool operator != (const SwigPyIterator& x) const;
SwigPyIterator& operator += (ptrdiff_t n);
SwigPyIterator& operator -= (ptrdiff_t n);
SwigPyIterator* operator + (ptrdiff_t n) const;
SwigPyIterator* operator - (ptrdiff_t n) const;
ptrdiff_t operator - (const SwigPyIterator& x) const;
};
}