summaryrefslogtreecommitdiff
path: root/scipy/weave/scxx/sequence.h
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2005-09-26 20:20:16 +0000
committerTravis Oliphant <oliphant@enthought.com>2005-09-26 20:20:16 +0000
commit45d01a4be1c4221132ba46d687e6af3a8df3329b (patch)
treece3be5290e918def7c7187e747c5460193b0ca85 /scipy/weave/scxx/sequence.h
parentccd1c3db37672627aa4fe0fdb5437f5dddc0fe86 (diff)
downloadnumpy-45d01a4be1c4221132ba46d687e6af3a8df3329b.tar.gz
Moved weave
Diffstat (limited to 'scipy/weave/scxx/sequence.h')
-rw-r--r--scipy/weave/scxx/sequence.h265
1 files changed, 265 insertions, 0 deletions
diff --git a/scipy/weave/scxx/sequence.h b/scipy/weave/scxx/sequence.h
new file mode 100644
index 000000000..1548e859c
--- /dev/null
+++ b/scipy/weave/scxx/sequence.h
@@ -0,0 +1,265 @@
+/********************************************
+ copyright 1999 McMillan Enterprises, Inc.
+ www.mcmillan-inc.com
+
+ modified for weave by eric jones
+*********************************************/
+#if !defined(SEQUENCE_H_INCLUDED_)
+#define SEQUENCE_H_INCLUDED_
+
+#include <string>
+#include <complex>
+
+#include "object.h"
+
+namespace py {
+
+//---------------------------------------------------------------------------
+// !! This isn't being picked up out of object.h for some reason, so I'll
+// !! redeclare it.
+//---------------------------------------------------------------------------
+void fail(PyObject*, const char* msg);
+
+//---------------------------------------------------------------------------
+// base class for list and tuple objects.
+//---------------------------------------------------------------------------
+class sequence : public object
+{
+public:
+ //-------------------------------------------------------------------------
+ // constructors
+ //-------------------------------------------------------------------------
+ sequence() : object() {};
+ sequence(const sequence& other) : object(other) {};
+ sequence(PyObject* obj) : object(obj) {
+ _violentTypeCheck();
+ };
+
+ //-------------------------------------------------------------------------
+ // destructors
+ //-------------------------------------------------------------------------
+ virtual ~sequence() {}
+
+ //-------------------------------------------------------------------------
+ // operator=
+ //-------------------------------------------------------------------------
+ virtual sequence& operator=(const sequence& other) {
+ grab_ref(other);
+ return *this;
+ };
+ /*virtual*/ sequence& operator=(const object& other) {
+ grab_ref(other);
+ _violentTypeCheck();
+ return *this;
+ };
+
+ //-------------------------------------------------------------------------
+ // type checking.
+ //-------------------------------------------------------------------------
+ virtual void _violentTypeCheck() {
+ if (!PySequence_Check(_obj)) {
+ grab_ref(0);
+ fail(PyExc_TypeError, "Not a sequence");
+ }
+ };
+
+ //-------------------------------------------------------------------------
+ // operator+ -- concatenation
+ //-------------------------------------------------------------------------
+ sequence operator+(const sequence& rhs) const {
+ PyObject* rslt = PySequence_Concat(_obj, rhs);
+ if (rslt==0)
+ fail(PyExc_TypeError, "Improper rhs for +");
+ return lose_ref(rslt);
+ };
+
+ //-------------------------------------------------------------------------
+ // count -- count the number of objects in a sequence.
+ //-------------------------------------------------------------------------
+ int count(const object& value) const {
+ int rslt = PySequence_Count(_obj, value);
+ if (rslt == -1)
+ fail(PyExc_RuntimeError, "failure in count");
+ return rslt;
+ };
+ int count(int value) const {
+ object val = value;
+ return count(val);
+ };
+ int count(double value) const {
+ object val = value;
+ return count(val);
+ };
+ int count(char* value) const {
+ object val = value;
+ return count(val);
+ };
+ int count(std::string& value) const {
+ object val = value.c_str();
+ return count(val);
+ };
+
+ //-------------------------------------------------------------------------
+ // set_item -- virtual so that set_item for tuple and list use
+ // type specific xxx_SetItem function calls.
+ //-------------------------------------------------------------------------
+ virtual void set_item(int ndx, object& val) {
+ int rslt = PySequence_SetItem(_obj, ndx, val);
+ if (rslt==-1)
+ fail(PyExc_IndexError, "Index out of range");
+ };
+
+
+ //-------------------------------------------------------------------------
+ // operator[] -- non-const version defined in list and tuple sub-types.
+ //-------------------------------------------------------------------------
+ object operator [] (int i) {
+ PyObject* o = PySequence_GetItem(_obj, i);
+ // don't throw error for when [] fails because it might be on left hand
+ // side (a[0] = 1). If the sequence 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 lose_ref(o);
+ };
+
+ //-------------------------------------------------------------------------
+ // slice -- handles slice operations.
+ // !! NOT TESTED
+ //-------------------------------------------------------------------------
+ sequence slice(int lo, int hi) const {
+ PyObject* o = PySequence_GetSlice(_obj, lo, hi);
+ if (o == 0)
+ fail(PyExc_IndexError, "could not obtain slice");
+ return lose_ref(o);
+ };
+
+ //-------------------------------------------------------------------------
+ // in -- find whether a value is in the given sequence.
+ // overloaded to handle the standard types used in weave.
+ //-------------------------------------------------------------------------
+ bool in(const object& value) const {
+ int rslt = PySequence_In(_obj, value);
+ if (rslt==-1)
+ fail(PyExc_RuntimeError, "problem in in");
+ return (rslt==1);
+ };
+ bool sequence::in(int value) const {
+ object val = value;
+ return in(val);
+ };
+ bool sequence::in(double value) const {
+ object val = value;
+ return in(val);
+ };
+ bool sequence::in(const std::complex<double>& value) const {
+ object val = value;
+ return in(val);
+ };
+ bool sequence::in(const char* value) const {
+ object val = value;
+ return in(val);
+ };
+ bool sequence::in(const std::string& value) const {
+ object val = value.c_str();
+ return in(val);
+ };
+
+ //-------------------------------------------------------------------------
+ // index -- find whether a value is in the given sequence.
+ // overloaded to handle the standard types used in weave.
+ //-------------------------------------------------------------------------
+ int index(const object& value) const {
+ int rslt = PySequence_Index(_obj, value);
+ if (rslt==-1)
+ fail(PyExc_IndexError, "value not found");
+ return rslt;
+ };
+ int sequence::index(int value) const {
+ object val = value;
+ return index(val);
+ };
+ int sequence::index(double value) const {
+ object val = value;
+ return index(val);
+ };
+ int sequence::index(const std::complex<double>& value) const {
+ object val = value;
+ return index(val);
+ };
+ int sequence::index(const char* value) const {
+ object val = value;
+ return index(val);
+ };
+ int sequence::index(const std::string& value) const {
+ object val = value;
+ return index(val);
+ };
+
+ //-------------------------------------------------------------------------
+ // len, length, size -- find the length of the sequence.
+ // version inherited from py::object ok.
+ //-------------------------------------------------------------------------
+
+ //-------------------------------------------------------------------------
+ // operator* -- repeat a list multiple times.
+ //-------------------------------------------------------------------------
+ sequence operator * (int count) const {
+ PyObject* rslt = PySequence_Repeat(_obj, count);
+ if (rslt==0)
+ fail(PyExc_RuntimeError, "sequence repeat failed");
+ return lose_ref(rslt);
+ };
+};
+
+//---------------------------------------------------------------------------
+// indexed_ref -- return reference obj when operator[] is used as an lvalue.
+//
+// list and tuple objects return this for non-const calls to operator[].
+// It is similar to object::keyed_ref, except that it stores an integer
+// index instead of py::object key.
+//---------------------------------------------------------------------------
+class indexed_ref : public object
+{
+ sequence& _parent;
+ int _ndx;
+public:
+ indexed_ref::indexed_ref(PyObject* obj, sequence& parent, int ndx)
+ : object(obj), _parent(parent), _ndx(ndx) { };
+ virtual ~indexed_ref() {};
+
+ indexed_ref& indexed_ref::operator=(const object& other) {
+ grab_ref(other);
+ _parent.set_item(_ndx, *this);
+ return *this;
+ };
+ indexed_ref& indexed_ref::operator=(int other) {
+ object oth = other;
+ return operator=(oth);
+ };
+ indexed_ref& indexed_ref::operator=(double other) {
+ object oth = other;
+ return operator=(oth);
+ };
+ indexed_ref& indexed_ref::operator=(const std::complex<double>& other) {
+ object oth = other;
+ return operator=(oth);
+ };
+ indexed_ref& indexed_ref::operator=(const char* other) {
+ object oth = other;
+ return operator=(oth);
+ };
+ indexed_ref& indexed_ref::operator=(const std::string& other) {
+ object oth = other;
+ return operator=(oth);
+ };
+};
+
+
+} // namespace py
+
+#endif // PWOSEQUENCE_H_INCLUDED_