dtype.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Copyright Jim Bosch 2010-2012.
  2. // Copyright Stefan Seefeld 2016.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef boost_python_numpy_dtype_hpp_
  7. #define boost_python_numpy_dtype_hpp_
  8. /**
  9. * @file boost/python/numpy/dtype.hpp
  10. * @brief Object manager for Python's numpy.dtype class.
  11. */
  12. #include <boost/python.hpp>
  13. #include <boost/python/numpy/config.hpp>
  14. #include <boost/python/numpy/numpy_object_mgr_traits.hpp>
  15. #include <boost/mpl/for_each.hpp>
  16. #include <boost/python/detail/type_traits.hpp>
  17. namespace boost { namespace python { namespace numpy {
  18. /**
  19. * @brief A boost.python "object manager" (subclass of object) for numpy.dtype.
  20. *
  21. * @todo This could have a lot more interesting accessors.
  22. */
  23. class BOOST_NUMPY_DECL dtype : public object {
  24. static python::detail::new_reference convert(object::object_cref arg, bool align);
  25. public:
  26. /// @brief Convert an arbitrary Python object to a data-type descriptor object.
  27. template <typename T>
  28. explicit dtype(T arg, bool align=false) : object(convert(arg, align)) {}
  29. /**
  30. * @brief Get the built-in numpy dtype associated with the given scalar template type.
  31. *
  32. * This is perhaps the most useful part of the numpy API: it returns the dtype object
  33. * corresponding to a built-in C++ type. This should work for any integer or floating point
  34. * type supported by numpy, and will also work for std::complex if
  35. * sizeof(std::complex<T>) == 2*sizeof(T).
  36. *
  37. * It can also be useful for users to add explicit specializations for POD structs
  38. * that return field-based dtypes.
  39. */
  40. template <typename T> static dtype get_builtin();
  41. /// @brief Return the size of the data type in bytes.
  42. int get_itemsize() const;
  43. /**
  44. * @brief Compare two dtypes for equivalence.
  45. *
  46. * This is more permissive than equality tests. For instance, if long and int are the same
  47. * size, the dtypes corresponding to each will be equivalent, but not equal.
  48. */
  49. friend BOOST_NUMPY_DECL bool equivalent(dtype const & a, dtype const & b);
  50. /**
  51. * @brief Register from-Python converters for NumPy's built-in array scalar types.
  52. *
  53. * This is usually called automatically by initialize(), and shouldn't be called twice
  54. * (doing so just adds unused converters to the Boost.Python registry).
  55. */
  56. static void register_scalar_converters();
  57. BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(dtype, object);
  58. };
  59. BOOST_NUMPY_DECL bool equivalent(dtype const & a, dtype const & b);
  60. namespace detail
  61. {
  62. template <int bits, bool isUnsigned> dtype get_int_dtype();
  63. template <int bits> dtype get_float_dtype();
  64. template <int bits> dtype get_complex_dtype();
  65. template <typename T, bool isInt=boost::is_integral<T>::value>
  66. struct builtin_dtype;
  67. template <typename T>
  68. struct builtin_dtype<T,true> {
  69. static dtype get() { return get_int_dtype< 8*sizeof(T), boost::is_unsigned<T>::value >(); }
  70. };
  71. template <>
  72. struct BOOST_NUMPY_DECL builtin_dtype<bool,true> {
  73. static dtype get();
  74. };
  75. template <typename T>
  76. struct builtin_dtype<T,false> {
  77. static dtype get() { return get_float_dtype< 8*sizeof(T) >(); }
  78. };
  79. template <typename T>
  80. struct builtin_dtype< std::complex<T>, false > {
  81. static dtype get() { return get_complex_dtype< 16*sizeof(T) >(); }
  82. };
  83. } // namespace detail
  84. template <typename T>
  85. inline dtype dtype::get_builtin() { return detail::builtin_dtype<T>::get(); }
  86. } // namespace boost::python::numpy
  87. namespace converter {
  88. NUMPY_OBJECT_MANAGER_TRAITS(numpy::dtype);
  89. }}} // namespace boost::python::converter
  90. #endif