diff options
Diffstat (limited to 'scipy/weave/scxx/tuple.h')
-rw-r--r-- | scipy/weave/scxx/tuple.h | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/scipy/weave/scxx/tuple.h b/scipy/weave/scxx/tuple.h new file mode 100644 index 000000000..895e50c8a --- /dev/null +++ b/scipy/weave/scxx/tuple.h @@ -0,0 +1,86 @@ +#if !defined(TUPLE_H_INCLUDED_) +#define TUPLE_H_INCLUDED_ + +#include "sequence.h" +#include <string> + +namespace py { + +class tuple : public sequence +{ +public: + + //------------------------------------------------------------------------- + // constructors + //------------------------------------------------------------------------- + tuple(int sz=0) : sequence (PyTuple_New(sz)) { lose_ref(_obj); } + tuple(const tuple& other) : sequence(other) { } + tuple(PyObject* obj) : sequence(obj) { _violentTypeCheck(); } + tuple::tuple(const list& lst) + : sequence (PyList_AsTuple(lst)) { lose_ref(_obj); } + + //------------------------------------------------------------------------- + // destructor + //------------------------------------------------------------------------- + virtual ~tuple() {}; + + //------------------------------------------------------------------------- + // operator= + //------------------------------------------------------------------------- + virtual tuple& operator=(const tuple& other) { + grab_ref(other); + return *this; + }; + /*virtual*/ tuple& operator=(const object& other) { + grab_ref(other); + _violentTypeCheck(); + return *this; + }; + + //------------------------------------------------------------------------- + // type checking + //------------------------------------------------------------------------- + virtual void _violentTypeCheck() { + if (!PyTuple_Check(_obj)) { + grab_ref(0); + fail(PyExc_TypeError, "Not a Python Tuple"); + } + }; + + //------------------------------------------------------------------------- + // set_item + // + // We have to do a little extra checking here, because tuples can only + // be assigned to if there is only a single reference to them. + //------------------------------------------------------------------------- + virtual void set_item(int ndx, object& val) { + if (_obj->ob_refcnt != 1) + fail(PyExc_TypeError,"Tuples values can't be set if ref count > 1\n"); + int rslt = PyTuple_SetItem(_obj, ndx, val); + val.disown(); //when using PyTuple_SetItem, he steals my reference + if (rslt==-1) + throw 1; + }; + + //------------------------------------------------------------------------- + // operator[] -- const and non-const versions of element access. + //------------------------------------------------------------------------- + indexed_ref tuple::operator [] (int i) { + // get a "borrowed" refcount + PyObject* o = PyTuple_GetItem(_obj, i); + // don't throw error for when [] fails because it might be on left hand + // side (a[0] = 1). If the tuple was just created, it will be filled + // with NULL values, and setting the values should be ok. However, we + // do want to catch index errors that might occur on the right hand side + // (obj = a[4] when a has len==3). + if (!o) { + if (PyErr_ExceptionMatches(PyExc_IndexError)) + throw 1; + } + return indexed_ref(o, *this, i); // this increfs + }; +};// class tuple + +} // namespace + +#endif // TUPLE_H_INCLUDED_ |