ultimatepp/bazaar/CoreBoostPy/Value.cpp
2011-05-16 20:32:29 +00:00

258 lines
No EOL
5.7 KiB
C++

#include "Value.h"
using namespace boost::python;
NAMESPACE_UPP
struct Value_to_python
{
static PyObject* convert(const Value& v)
{
switch(v.GetType())
{
case INT_V: return incref(object(int(v)).ptr());
case BOOL_V: return incref(object(bool(v)).ptr());
case INT64_V: return incref(object(int64(v)).ptr());
case DOUBLE_V: return incref(object(double(v)).ptr());
case STRING_V: return incref(object(String(v)).ptr());
case VALUEARRAY_V: return incref(object(ValueArray(v)).ptr());
case VALUEMAP_V: return incref(object(ValueMap(v)).ptr());
case COLOR_V: return incref(object(Color(v)).ptr());
case POINT_V: return incref(object(Point(v)).ptr());
case SIZE_V: return incref(object(Size(v)).ptr());
case RECT_V: return incref(object(Rect(v)).ptr());
case VOID_V:
default: return incref(object().ptr()); //none
}
}
};
struct Value_from_python
{
Value_from_python()
{
converter::registry::push_back(&convertible, &construct, type_id<Value>());
}
static void* convertible(PyObject* po)
{
if(po == Py_None) return po;
if(PyBool_Check(po)) return po;
if(PyInt_Check(po)) return po;
if(PyLong_Check(po)) return po;
if(PyFloat_Check(po)) return po;
if(PyString_Check(po)) return po;
if(PyList_Check(po)) return po;
if(PyDict_Check(po)) return po;
if(extract<Color>(po).check()) return po;
if(extract<Point>(po).check()) return po;
if(extract<Size>(po).check()) return po;
if(extract<Rect>(po).check()) return po;
return 0;
}
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data)
{
void* d = ((converter::rvalue_from_python_storage<Value>*)data)->storage.bytes;
if(po == Py_None)
{
new(d) Value();
}
else
if(PyBool_Check(po)) //before Int, cause bool is derived from PyTypeInt
{
bool c = false;
if(po != Py_False) {
if(po != Py_True) throw_error_already_set();
c = true;
}
new(d) Value(c);
}
else
if(PyInt_Check(po))
{
long c = PyInt_AsLong(po);
new(d) Value(int(c));
}
else
//notmally here bool
if(PyLong_Check(po))
{
long long c = PyLong_AsLongLong(po);
new(d) Value(c);
}
else
if(PyFloat_Check(po))
{
double c = PyFloat_AsDouble(po);
new(d) Value(c);
}
else
if(PyString_Check(po))
{
String c = extract<String>(po); //use upper converter
new(d) Value(c);
}
else
if(PyList_Check(po))
{
ValueArray c = extract<ValueArray>(po); //use upper converter
new(d) Value(c);
}
else
if(PyDict_Check(po))
{
ValueMap c = extract<ValueMap>(po); //use upper converter
new(d) Value(c);
}
else
if(extract<Color>(po).check())
{
Color c = extract<Color>(po); //use upper converter
new(d) Value(c.operator Value());
}
else
if(extract<Point>(po).check())
{
Point c = extract<Point>(po); //use upper converter
new(d) Value(c.operator Value());
}
else
if(extract<Size>(po).check())
{
Size c = extract<Size>(po); //use upper converter
new(d) Value(c.operator Value());
}
else
if(extract<Rect>(po).check())
{
Rect c = extract<Rect>(po); //use upper converter
new(d) Value(c.operator Value());
}
else
{
throw_error_already_set(); //FIXME dont know type, which to throw?
}
data->convertible = d;
}
};
void export_Value()
{
ONCELOCK
{
to_python_converter<Value, Value_to_python>();
Value_from_python();
}
}
//ValueArray
struct ValueArray_to_python
{
static PyObject* convert(const ValueArray& v)
{
list l;
const Vector<Value>& vv = v.Get();
for(int i = 0; i < vv.GetCount(); i++)
l.append(object(vv[i]));
return incref(l.ptr()); //need to create a list
}
};
struct ValueArray_from_python
{
ValueArray_from_python()
{
converter::registry::push_back(&convertible, &construct, type_id<ValueArray>());
}
static void* convertible(PyObject* po)
{
if(PyList_Check(po)) return po;
return 0;
}
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data)
{
void* d = ((converter::rvalue_from_python_storage<ValueArray>*)data)->storage.bytes;
Vector<Value> vv;
list l(handle<>(borrowed(po)));
for(int i = 0; i < len(l); i++)
vv.Add(extract<Value>(l[i]));
new(d) ValueArray(vv);
data->convertible = d;
}
};
void export_ValueArray()
{
ONCELOCK
{
to_python_converter<ValueArray, ValueArray_to_python>();
ValueArray_from_python();
}
}
//ValueMap
struct ValueMap_to_python
{
static PyObject* convert(const ValueMap& v)
{
dict dt;
const Index<Value>& k = v.GetKeys();
const Vector<Value>& vv = v.GetValues().Get();
ASSERT(k.GetCount() == vv.GetCount());
for(int i = 0; i < k.GetCount(); i++)
dt[object(k[i])] = object(vv[i]);
return incref(dt.ptr()); //need to create a list
}
};
struct ValueMap_from_python
{
ValueMap_from_python()
{
converter::registry::push_back(&convertible, &construct, type_id<ValueMap>());
}
static void* convertible(PyObject* po)
{
if(PyDict_Check(po)) return po;
return 0;
}
static void construct(PyObject* po, converter::rvalue_from_python_stage1_data* data)
{
void* d = ((converter::rvalue_from_python_storage<ValueMap>*)data)->storage.bytes;
Index<Value> k;
Vector<Value> vv;
dict dt(handle<>(borrowed(po)));
list lk = dt.keys();
list lv = dt.values();
for(int i = 0; i < len(dt); i++)
{
k.Add(extract<Value>(lk[i]));
vv.Add(extract<Value>(lv[i]));
}
new(d) ValueMap(k, vv);
data->convertible = d;
}
};
void export_ValueMap()
{
ONCELOCK
{
to_python_converter<ValueMap, ValueMap_to_python>();
ValueMap_from_python();
}
}
END_UPP_NAMESPACE