summaryrefslogtreecommitdiff
path: root/boost/python/numpy/dtype.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/python/numpy/dtype.hpp')
-rw-r--r--boost/python/numpy/dtype.hpp117
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