Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #define BOOST_NUMPY_INTERNAL
00007 #include <boost/numpy/internal.hpp>
00008
00009 #define DTYPE_FROM_CODE(code) \
00010 dtype(python::detail::new_reference(reinterpret_cast<PyObject*>(PyArray_DescrFromType(code))))
00011
00012 #define BUILTIN_INT_DTYPE(bits) \
00013 template <> struct builtin_int_dtype< bits, false > { \
00014 static dtype get() { return DTYPE_FROM_CODE(NPY_INT ## bits); } \
00015 }; \
00016 template <> struct builtin_int_dtype< bits, true > { \
00017 static dtype get() { return DTYPE_FROM_CODE(NPY_UINT ## bits); } \
00018 }; \
00019 template dtype get_int_dtype< bits, false >(); \
00020 template dtype get_int_dtype< bits, true >()
00021
00022 #define BUILTIN_FLOAT_DTYPE(bits) \
00023 template <> struct builtin_float_dtype< bits > { \
00024 static dtype get() { return DTYPE_FROM_CODE(NPY_FLOAT ## bits); } \
00025 }; \
00026 template dtype get_float_dtype< bits >()
00027
00028 #define BUILTIN_COMPLEX_DTYPE(bits) \
00029 template <> struct builtin_complex_dtype< bits > { \
00030 static dtype get() { return DTYPE_FROM_CODE(NPY_COMPLEX ## bits); } \
00031 }; \
00032 template dtype get_complex_dtype< bits >()
00033
00034 namespace boost { namespace python { namespace converter {
00035 NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyArrayDescr_Type, numpy::dtype)
00036 }}}
00037
00038 namespace boost { namespace numpy {
00039
00040 namespace detail {
00041
00042 dtype builtin_dtype<bool,true>::get() { return DTYPE_FROM_CODE(NPY_BOOL); }
00043
00044 template <int bits, bool isUnsigned> struct builtin_int_dtype;
00045 template <int bits> struct builtin_float_dtype;
00046 template <int bits> struct builtin_complex_dtype;
00047
00048 template <int bits, bool isUnsigned> dtype get_int_dtype() {
00049 return builtin_int_dtype<bits,isUnsigned>::get();
00050 }
00051 template <int bits> dtype get_float_dtype() { return builtin_float_dtype<bits>::get(); }
00052 template <int bits> dtype get_complex_dtype() { return builtin_complex_dtype<bits>::get(); }
00053
00054 BUILTIN_INT_DTYPE(8);
00055 BUILTIN_INT_DTYPE(16);
00056 BUILTIN_INT_DTYPE(32);
00057 BUILTIN_INT_DTYPE(64);
00058 BUILTIN_FLOAT_DTYPE(32);
00059 BUILTIN_FLOAT_DTYPE(64);
00060 BUILTIN_COMPLEX_DTYPE(64);
00061 BUILTIN_COMPLEX_DTYPE(128);
00062 #if NPY_BITSOF_LONGDOUBLE > NPY_BITSOF_DOUBLE
00063 template <> struct builtin_float_dtype< NPY_BITSOF_LONGDOUBLE > {
00064 static dtype get() { return DTYPE_FROM_CODE(NPY_LONGDOUBLE); }
00065 };
00066 template dtype get_float_dtype< NPY_BITSOF_LONGDOUBLE >();
00067 template <> struct builtin_complex_dtype< 2 * NPY_BITSOF_LONGDOUBLE > {
00068 static dtype get() { return DTYPE_FROM_CODE(NPY_CLONGDOUBLE); }
00069 };
00070 template dtype get_complex_dtype< 2 * NPY_BITSOF_LONGDOUBLE >();
00071 #endif
00072
00073 }
00074
00075 python::detail::new_reference dtype::convert(python::object const & arg, bool align) {
00076 PyArray_Descr* obj=NULL;
00077 if (align) {
00078 if (PyArray_DescrAlignConverter(arg.ptr(), &obj) < 0)
00079 python::throw_error_already_set();
00080 } else {
00081 if (PyArray_DescrConverter(arg.ptr(), &obj) < 0)
00082 python::throw_error_already_set();
00083 }
00084 return python::detail::new_reference(reinterpret_cast<PyObject*>(obj));
00085 }
00086
00087 int dtype::get_itemsize() const { return reinterpret_cast<PyArray_Descr*>(ptr())->elsize;}
00088
00089 bool equivalent(dtype const & a, dtype const & b) {
00090 return PyArray_EquivTypes(
00091 reinterpret_cast<PyArray_Descr*>(a.ptr()),
00092 reinterpret_cast<PyArray_Descr*>(b.ptr())
00093 );
00094 }
00095
00096 namespace {
00097
00098 namespace pyconv = boost::python::converter;
00099
00100 template <typename T>
00101 class array_scalar_converter {
00102 public:
00103
00104 static PyTypeObject const * get_pytype() {
00105
00106
00107
00108
00109
00110
00111 return reinterpret_cast<PyArray_Descr*>(dtype::get_builtin<T>().ptr())->typeobj;
00112 }
00113
00114 static void * convertible(PyObject * obj) {
00115 if (obj->ob_type == get_pytype()) {
00116 return obj;
00117 } else {
00118 return 0;
00119 }
00120 }
00121
00122 static void convert(PyObject * obj, pyconv::rvalue_from_python_stage1_data* data) {
00123 void * storage = reinterpret_cast<pyconv::rvalue_from_python_storage<T>*>(data)->storage.bytes;
00124
00125
00126 PyArray_ScalarAsCtype(obj, reinterpret_cast<T*>(storage));
00127 data->convertible = storage;
00128 }
00129
00130 static void declare() {
00131 pyconv::registry::push_back(
00132 &convertible, &convert, python::type_id<T>()
00133 #ifndef BOOST_PYTHON_NO_PY_SIGNATURES
00134 , &get_pytype
00135 #endif
00136 );
00137 }
00138
00139 };
00140
00141 }
00142
00143 void dtype::register_scalar_converters() {
00144 array_scalar_converter<bool>::declare();
00145 array_scalar_converter<npy_uint8>::declare();
00146 array_scalar_converter<npy_int8>::declare();
00147 array_scalar_converter<npy_uint16>::declare();
00148 array_scalar_converter<npy_int16>::declare();
00149 array_scalar_converter<npy_uint32>::declare();
00150 array_scalar_converter<npy_int32>::declare();
00151 array_scalar_converter<npy_uint64>::declare();
00152 array_scalar_converter<npy_int64>::declare();
00153 array_scalar_converter<float>::declare();
00154 array_scalar_converter<double>::declare();
00155 array_scalar_converter< std::complex<float> >::declare();
00156 array_scalar_converter< std::complex<double> >::declare();
00157 #if NPY_BITSOF_LONGDOUBLE > NPY_BITSOF_DOUBLE
00158 array_scalar_converter<long double>::declare();
00159 array_scalar_converter< std::complex<long double> >::declare();
00160 #endif
00161 }
00162
00163 }
00164 }