1 | // Copyright David Abrahams 2002. |
2 | // Distributed under the Boost Software License, Version 1.0. (See |
3 | // accompanying file LICENSE_1_0.txt or copy at |
4 | // http://www.boost.org/LICENSE_1_0.txt) |
5 | #ifndef ENUM_DWA200298_HPP |
6 | # define ENUM_DWA200298_HPP |
7 | |
8 | # include <boost/python/detail/prefix.hpp> |
9 | |
10 | # include <boost/python/object/enum_base.hpp> |
11 | # include <boost/python/converter/rvalue_from_python_data.hpp> |
12 | # include <boost/python/converter/registered.hpp> |
13 | |
14 | namespace boost { namespace python { |
15 | |
16 | template <class T> |
17 | struct enum_ : public objects::enum_base |
18 | { |
19 | typedef objects::enum_base base; |
20 | |
21 | // Declare a new enumeration type in the current scope() |
22 | enum_(char const* name, char const* doc = 0); |
23 | |
24 | // Add a new enumeration value with the given name and value. |
25 | inline enum_<T>& value(char const* name, T); |
26 | |
27 | // Add all of the defined enumeration values to the current scope with the |
28 | // same names used here. |
29 | inline enum_<T>& export_values(); |
30 | private: |
31 | static PyObject* to_python(void const* x); |
32 | static void* convertible_from_python(PyObject* obj); |
33 | static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data); |
34 | }; |
35 | |
36 | template <class T> |
37 | inline enum_<T>::enum_(char const* name, char const* doc ) |
38 | : base( |
39 | name |
40 | , &enum_<T>::to_python |
41 | , &enum_<T>::convertible_from_python |
42 | , &enum_<T>::construct |
43 | , type_id<T>() |
44 | , doc |
45 | ) |
46 | { |
47 | } |
48 | |
49 | // This is the conversion function that gets registered for converting |
50 | // these enums to Python. |
51 | template <class T> |
52 | PyObject* enum_<T>::to_python(void const* x) |
53 | { |
54 | return base::to_python( |
55 | converter::registered<T>::converters.m_class_object |
56 | , static_cast<long>(*(T const*)x)); |
57 | } |
58 | |
59 | // |
60 | // The following two static functions serve as the elements of an |
61 | // rvalue from_python converter for the enumeration type. |
62 | // |
63 | |
64 | // This checks that a given Python object can be converted to the |
65 | // enumeration type. |
66 | template <class T> |
67 | void* enum_<T>::convertible_from_python(PyObject* obj) |
68 | { |
69 | return PyObject_IsInstance( |
70 | obj |
71 | , upcast<PyObject>( |
72 | converter::registered<T>::converters.m_class_object)) |
73 | |
74 | ? obj : 0; |
75 | } |
76 | |
77 | // Constructs an instance of the enumeration type in the from_python |
78 | // data. |
79 | template <class T> |
80 | void enum_<T>::construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data) |
81 | { |
82 | #if PY_VERSION_HEX >= 0x03000000 |
83 | T x = static_cast<T>(PyLong_AS_LONG(obj)); |
84 | #else |
85 | T x = static_cast<T>(PyInt_AS_LONG(obj)); |
86 | #endif |
87 | void* const storage = ((converter::rvalue_from_python_storage<T>*)data)->storage.bytes; |
88 | new (storage) T(x); |
89 | data->convertible = storage; |
90 | } |
91 | |
92 | template <class T> |
93 | inline enum_<T>& enum_<T>::value(char const* name, T x) |
94 | { |
95 | this->add_value(name, static_cast<long>(x)); |
96 | return *this; |
97 | } |
98 | |
99 | template <class T> |
100 | inline enum_<T>& enum_<T>::export_values() |
101 | { |
102 | this->base::export_values(); |
103 | return *this; |
104 | } |
105 | |
106 | }} // namespace boost::python |
107 | |
108 | #endif // ENUM_DWA200298_HPP |
109 | |