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 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
|
/********************************************
copyright 1999 McMillan Enterprises, Inc.
www.mcmillan-inc.com
modified for weave by eric jones
*********************************************/
#if !defined(DICT_H_INCLUDED_)
#define DICT_H_INCLUDED_
#include <string>
#include "object.h"
#include "list.h"
namespace py {
class dict : public object
{
public:
//-------------------------------------------------------------------------
// constructors
//-------------------------------------------------------------------------
dict() : object (PyDict_New()) { lose_ref(_obj); }
dict(const dict& other) : object(other) {};
dict(PyObject* obj) : object(obj) {
_violentTypeCheck();
};
//-------------------------------------------------------------------------
// destructor
//-------------------------------------------------------------------------
virtual ~dict() {};
//-------------------------------------------------------------------------
// operator=
//-------------------------------------------------------------------------
virtual dict& operator=(const dict& other) {
grab_ref(other);
return *this;
};
dict& operator=(const object& other) {
grab_ref(other);
_violentTypeCheck();
return *this;
};
//-------------------------------------------------------------------------
// type checking
//-------------------------------------------------------------------------
virtual void _violentTypeCheck() {
if (!PyDict_Check(_obj)) {
grab_ref(0);
fail(PyExc_TypeError, "Not a dictionary");
}
};
//-------------------------------------------------------------------------
// get -- object, numeric, and string versions
//-------------------------------------------------------------------------
object get (object& key) {
object rslt = PyDict_GetItem(_obj, key);
return rslt;
};
object get (int key) {
object _key = object(key);
return get(_key);
};
object get (double key) {
object _key = object(key);
return get(_key);
};
object get (const std::complex<double>& key) {
object _key = object(key);
return get(_key);
};
object get (const char* key) {
object rslt = PyDict_GetItemString(_obj, (char*) key);
return rslt;
};
object get (const std::string& key) {
return get(key.c_str());
};
object get (char key) {
return get(&key);
};
//-------------------------------------------------------------------------
// operator[] -- object and numeric versions
//-------------------------------------------------------------------------
keyed_ref operator [] (object& key) {
object rslt = PyDict_GetItem(_obj, key);
if (!(PyObject*)rslt)
PyErr_Clear(); // Ignore key errors
return keyed_ref(rslt, *this, key);
};
keyed_ref operator [] (int key) {
object _key = object(key);
return operator [](_key);
};
keyed_ref operator [] (double key) {
object _key = object(key);
return operator [](_key);
};
keyed_ref operator [] (const std::complex<double>& key) {
object _key = object(key);
return operator [](_key);
};
//-------------------------------------------------------------------------
// operator[] non-const -- string versions
//-------------------------------------------------------------------------
keyed_ref operator [] (const char* key) {
object rslt = PyDict_GetItemString(_obj, (char*) key);
if (!(PyObject*)rslt)
PyErr_Clear(); // Ignore key errors
object _key = key;
return keyed_ref(rslt, *this, _key);
};
keyed_ref operator [] (const std::string& key) {
return operator [](key.c_str());
};
keyed_ref operator [] (char key) {
return operator [](&key);
};
//-------------------------------------------------------------------------
// has_key -- object and numeric versions
//-------------------------------------------------------------------------
bool has_key(object& key) const {
return PyMapping_HasKey(_obj, key)==1;
};
bool has_key(int key) const {
object _key = key;
return has_key(_key);
};
bool has_key(double key) const {
object _key = key;
return has_key(_key);
};
bool has_key(const std::complex<double>& key) const {
object _key = key;
return has_key(_key);
};
//-------------------------------------------------------------------------
// has_key -- string versions
//-------------------------------------------------------------------------
bool has_key(const char* key) const {
return PyMapping_HasKeyString(_obj, (char*) key)==1;
};
bool has_key(const std::string& key) const {
return has_key(key.c_str());
};
bool has_key(char key) const {
return has_key(&key);
};
//-------------------------------------------------------------------------
// len and length methods
//-------------------------------------------------------------------------
int len() const {
return PyDict_Size(_obj);
}
int length() const {
return PyDict_Size(_obj);
};
//-------------------------------------------------------------------------
// set_item
//-------------------------------------------------------------------------
virtual void set_item(const char* key, object& val) {
int rslt = PyDict_SetItemString(_obj, (char*) key, val);
if (rslt==-1)
fail(PyExc_RuntimeError, "Cannot add key / value");
};
virtual void set_item(object& key, object& val) const {
int rslt = PyDict_SetItem(_obj, key, val);
if (rslt==-1)
fail(PyExc_KeyError, "Key must be hashable");
};
//-------------------------------------------------------------------------
// clear
//-------------------------------------------------------------------------
void clear() {
PyDict_Clear(_obj);
};
//-------------------------------------------------------------------------
// update
//-------------------------------------------------------------------------
#if PY_VERSION_HEX >= 0x02020000
void update(dict& other) {
PyDict_Merge(_obj,other,1);
};
#endif
//-------------------------------------------------------------------------
// del -- remove key from dictionary
// overloaded to take all common weave types
//-------------------------------------------------------------------------
void del(object& key) {
int rslt = PyDict_DelItem(_obj, key);
if (rslt==-1)
fail(PyExc_KeyError, "Key not found");
};
void del(int key) {
object _key = key;
del(_key);
};
void del(double key) {
object _key = key;
del(_key);
};
void del(const std::complex<double>& key) {
object _key = key;
del(_key);
};
void del(const char* key) {
int rslt = PyDict_DelItemString(_obj, (char*) key);
if (rslt==-1)
fail(PyExc_KeyError, "Key not found");
};
void del(const std::string key) {
del(key.c_str());
};
//-------------------------------------------------------------------------
// items, keys, and values
//-------------------------------------------------------------------------
list items() const {
PyObject* rslt = PyDict_Items(_obj);
if (rslt==0)
fail(PyExc_RuntimeError, "failed to get items");
return lose_ref(rslt);
};
list keys() const {
PyObject* rslt = PyDict_Keys(_obj);
if (rslt==0)
fail(PyExc_RuntimeError, "failed to get keys");
return lose_ref(rslt);
};
list values() const {
PyObject* rslt = PyDict_Values(_obj);
if (rslt==0)
fail(PyExc_RuntimeError, "failed to get values");
return lose_ref(rslt);
};
};
} // namespace
#endif // DICT_H_INCLUDED_
|