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