diff options
Diffstat (limited to 'boost/python/numpy/dtype.hpp')
-rw-r--r-- | boost/python/numpy/dtype.hpp | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/boost/python/numpy/dtype.hpp b/boost/python/numpy/dtype.hpp new file mode 100644 index 0000000000..1284f9e5d8 --- /dev/null +++ b/boost/python/numpy/dtype.hpp @@ -0,0 +1,117 @@ +// Copyright Jim Bosch 2010-2012. +// Copyright Stefan Seefeld 2016. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef boost_python_numpy_dtype_hpp_ +#define boost_python_numpy_dtype_hpp_ + +/** + * @file boost/python/numpy/dtype.hpp + * @brief Object manager for Python's numpy.dtype class. + */ + +#include <boost/python.hpp> +#include <boost/python/numpy/numpy_object_mgr_traits.hpp> + +#include <boost/mpl/for_each.hpp> +#include <boost/type_traits/add_pointer.hpp> + +namespace boost { namespace python { namespace numpy { + +/** + * @brief A boost.python "object manager" (subclass of object) for numpy.dtype. + * + * @todo This could have a lot more interesting accessors. + */ +class dtype : public object { + static python::detail::new_reference convert(object::object_cref arg, bool align); +public: + + /// @brief Convert an arbitrary Python object to a data-type descriptor object. + template <typename T> + explicit dtype(T arg, bool align=false) : object(convert(arg, align)) {} + + /** + * @brief Get the built-in numpy dtype associated with the given scalar template type. + * + * This is perhaps the most useful part of the numpy API: it returns the dtype object + * corresponding to a built-in C++ type. This should work for any integer or floating point + * type supported by numpy, and will also work for std::complex if + * sizeof(std::complex<T>) == 2*sizeof(T). + * + * It can also be useful for users to add explicit specializations for POD structs + * that return field-based dtypes. + */ + template <typename T> static dtype get_builtin(); + + /// @brief Return the size of the data type in bytes. + int get_itemsize() const; + + /** + * @brief Compare two dtypes for equivalence. + * + * This is more permissive than equality tests. For instance, if long and int are the same + * size, the dtypes corresponding to each will be equivalent, but not equal. + */ + friend bool equivalent(dtype const & a, dtype const & b); + + /** + * @brief Register from-Python converters for NumPy's built-in array scalar types. + * + * This is usually called automatically by initialize(), and shouldn't be called twice + * (doing so just adds unused converters to the Boost.Python registry). + */ + static void register_scalar_converters(); + + BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dtype, object); + +}; + +bool equivalent(dtype const & a, dtype const & b); + +namespace detail +{ + +template <int bits, bool isUnsigned> dtype get_int_dtype(); + +template <int bits> dtype get_float_dtype(); + +template <int bits> dtype get_complex_dtype(); + +template <typename T, bool isInt=boost::is_integral<T>::value> +struct builtin_dtype; + +template <typename T> +struct builtin_dtype<T,true> { + static dtype get() { return get_int_dtype< 8*sizeof(T), boost::is_unsigned<T>::value >(); } +}; + +template <> +struct builtin_dtype<bool,true> { + static dtype get(); +}; + +template <typename T> +struct builtin_dtype<T,false> { + static dtype get() { return get_float_dtype< 8*sizeof(T) >(); } +}; + +template <typename T> +struct builtin_dtype< std::complex<T>, false > { + static dtype get() { return get_complex_dtype< 16*sizeof(T) >(); } +}; + +} // namespace detail + +template <typename T> +inline dtype dtype::get_builtin() { return detail::builtin_dtype<T>::get(); } + +} // namespace boost::python::numpy + +namespace converter { +NUMPY_OBJECT_MANAGER_TRAITS(numpy::dtype); +}}} // namespace boost::python::converter + +#endif |