enum.hpp 2.9 KB

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