1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
|
/********************************************
copyright 1999 McMillan Enterprises, Inc.
www.mcmillan-inc.com
modified for weave by eric jones
*********************************************/
#if !defined(LIST_H_INCLUDED_)
#define LIST_H_INCLUDED_
// ej: not sure what this is about, but we'll leave it.
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "object.h"
#include "sequence.h"
#include <string>
#include <complex>
namespace py {
class list : public sequence
{
public:
//-------------------------------------------------------------------------
// constructors
//-------------------------------------------------------------------------
list(int size=0) : sequence (PyList_New(size)) { lose_ref(_obj); }
list(const list& other) : sequence(other) {};
list(PyObject* obj) : sequence(obj) {
_violentTypeCheck();
};
//-------------------------------------------------------------------------
// descructor
//-------------------------------------------------------------------------
virtual ~list() {};
//-------------------------------------------------------------------------
// operator=
//-------------------------------------------------------------------------
virtual list& operator=(const list& other) {
grab_ref(other);
return *this;
};
list& operator=(const object& other) {
grab_ref(other);
_violentTypeCheck();
return *this;
};
//-------------------------------------------------------------------------
// type checking
//-------------------------------------------------------------------------
virtual void _violentTypeCheck() {
if (!PyList_Check(_obj)) {
//should probably check the sequence methods for non-0 setitem
grab_ref(0);
fail(PyExc_TypeError, "Not a mutable sequence");
}
};
//-------------------------------------------------------------------------
// del -- remove the item at a given index from the list.
// also a two valued version for removing slices from a list.
//-------------------------------------------------------------------------
bool del(int i) {
int rslt = PySequence_DelItem(_obj, i);
if (rslt == -1)
fail(PyExc_RuntimeError, "cannot delete item");
return true;
};
bool del(int lo, int hi) {
int rslt = PySequence_DelSlice(_obj, lo, hi);
if (rslt == -1)
fail(PyExc_RuntimeError, "cannot delete slice");
return true;
};
//-------------------------------------------------------------------------
// operator[] -- access/set elements in a list
//-------------------------------------------------------------------------
indexed_ref operator [] (int i) {
PyObject* o = PyList_GetItem(_obj, i); // get a "borrowed" refcount
// don't throw error for when [] fails because it might be on left hand
// side (a[0] = 1). If the list 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
};
//-------------------------------------------------------------------------
// set_item -- set list entry at a given index to a new value.
//-------------------------------------------------------------------------
virtual void set_item(int ndx, object& val) {
//int rslt = PySequence_SetItem(_obj, ndx, val); - assumes old item is valid
int rslt = PyList_SetItem(_obj, ndx, val);
val.disown(); //when using PyList_SetItem, he steals my reference
if (rslt==-1)
fail(PyExc_IndexError, "Index out of range");
};
//-------------------------------------------------------------------------
// set_slice -- set slice to a new sequence of values
//
// !! NOT TESTED
//-------------------------------------------------------------------------
void set_slice(int lo, int hi, const sequence& slice) {
int rslt = PySequence_SetSlice(_obj, lo, hi, slice);
if (rslt==-1)
fail(PyExc_RuntimeError, "Error setting slice");
};
//-------------------------------------------------------------------------
// append -- add new item to end of list
// overloaded to accept all of the common weave types.
//-------------------------------------------------------------------------
list& append(const object& other) {
int rslt = PyList_Append(_obj, other);
if (rslt==-1) {
PyErr_Clear(); //Python sets one
fail(PyExc_RuntimeError, "Error appending");
}
return *this;
};
list& append(int other) {
object oth = other;
return append(oth);
};
list& append(double other) {
object oth = other;
return append(oth);
};
list& append(const std::complex<double>& other) {
object oth = other;
return append(oth);
};
list& append(const char* other) {
object oth = other;
return append(oth);
};
list& append(const std::string& other) {
object oth = other;
return append(oth);
};
//-------------------------------------------------------------------------
// insert -- insert a new item before the given index.
// overloaded to accept all of the common weave types.
//-------------------------------------------------------------------------
list& insert(int ndx, object& other) {
int rslt = PyList_Insert(_obj, ndx, other);
if (rslt==-1) {
PyErr_Clear(); //Python sets one
fail(PyExc_RuntimeError, "Error inserting");
};
return *this;
};
list& insert(int ndx, int other) {
object oth = other;
return insert(ndx, oth);
};
list& insert(int ndx, double other) {
object oth = other;
return insert(ndx, oth);
};
list& insert(int ndx, std::complex<double>& other) {
object oth = other;
return insert(ndx, oth);
};
list& insert(int ndx, const char* other) {
object oth = other;
return insert(ndx, oth);
};
list& insert(int ndx, const std::string& other) {
object oth = other;
return insert(ndx, oth);
};
//-------------------------------------------------------------------------
// reverse -- reverse the order of items in the list.
//-------------------------------------------------------------------------
list& reverse() {
int rslt = PyList_Reverse(_obj);
if (rslt==-1) {
PyErr_Clear(); //Python sets one
fail(PyExc_RuntimeError, "Error reversing");
};
return *this; //HA HA - Guido can't stop me!!!
};
//-------------------------------------------------------------------------
// sort -- sort the items in the list.
//-------------------------------------------------------------------------
list& sort() {
int rslt = PyList_Sort(_obj);
if (rslt==-1) {
PyErr_Clear(); //Python sets one
fail(PyExc_RuntimeError, "Error sorting");
};
return *this; //HA HA - Guido can't stop me!!!
};
}; // class list
} // namespace py
#endif // LIST_H_INCLUDED_
|