dtype.cpp
Go to the documentation of this file.
00001 // Copyright Jim Bosch 2010-2012.
00002 // Distributed under the Boost Software License, Version 1.0.
00003 //    (See accompanying file LICENSE_1_0.txt or copy at
00004 //          http://www.boost.org/LICENSE_1_0.txt)
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 }}} // namespace boost::python::converter
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 } // namespace detail
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         // This implementation depends on the fact that get_builtin returns pointers to objects
00106         // NumPy has declared statically, and that the typeobj member also refers to a static
00107         // object.  That means we don't need to do any reference counting.
00108         // In fact, I'm somewhat concerned that increasing the reference count of any of these
00109         // might cause leaks, because I don't think Boost.Python ever decrements it, but it's
00110         // probably a moot point if everything is actually static.
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         // We assume std::complex is a "standard layout" here and elsewhere; not guaranteed by
00125         // C++03 standard, but true in every known implementation (and guaranteed by C++11).
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 } // anonymous
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 } // namespace boost::numpy
00164 } // namespace boost


boost_numpy
Author(s): Jim Bosch, Ankit Daftery
autogenerated on Fri Aug 28 2015 10:10:40