2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-22 05:22:45 +00:00

Added support for enums

[SVN r15222]
This commit is contained in:
Dave Abrahams
2002-09-09 02:00:53 +00:00
parent 4c8bcd918b
commit dcf7e7cf0c
6 changed files with 117 additions and 32 deletions

View File

@@ -23,6 +23,7 @@ dll bpl
src/converter/from_python.cpp
src/converter/registry.cpp
src/converter/type_id.cpp
src/object/enum.cpp
src/object/class.cpp
src/object/function.cpp
src/object/inheritance.cpp

View File

@@ -0,0 +1,75 @@
// Copyright David Abrahams 2002. Permission to copy, use,
// modify, sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
#ifndef ENUM_DWA200298_HPP
# define ENUM_DWA200298_HPP
# include <boost/python/object/enum_base.hpp>
# include <boost/python/converter/rvalue_from_python_data.hpp>
namespace boost { namespace python {
template <class T>
struct enum_ : public objects::enum_base
{
enum_(char const* name);
inline enum_<T>& value(char const* name, T);
private:
static PyObject* to_python(void const* x);
static void* convertible(PyObject* obj);
static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data);
};
template <class T>
inline enum_<T>::enum_(char const* name)
: enum_base(
name
, &enum_<T>::to_python
, &enum_<T>::convertible
, &enum_<T>::construct
, type_id<T>())
{
}
// This is the conversion function that gets registered for converting
template <class T>
PyObject* enum_<T>::to_python(void const* x)
{
return enum_base::to_python(
converter::registered<T>::converters.class_object
, static_cast<long>(*(T const*)x));
}
template <class T>
void* enum_<T>::convertible(PyObject* obj)
{
return PyObject_IsInstance(
obj
, upcast<PyObject>(
converter::registered<T>::converters.class_object))
? obj : 0;
}
template <class T>
void enum_<T>::construct(PyObject* obj, converter::rvalue_from_python_stage1_data* data)
{
T x = static_cast<T>(PyInt_AS_LONG(obj));
void* const storage = ((converter::rvalue_from_python_storage<T>*)data)->storage.bytes;
new (storage) T(x);
data->convertible = storage;
}
template <class T>
inline enum_<T>& enum_<T>::value(char const* name, T x)
{
objects::enum_base::add_value(name, static_cast<long>(x));
return *this;
}
}} // namespace boost::python
#endif // ENUM_DWA200298_HPP

View File

@@ -18,6 +18,8 @@ namespace boost { namespace python {
class str : public object
{
public:
BOOST_PYTHON_DECL str(); // new str
BOOST_PYTHON_DECL str(const char* s); // new str
explicit BOOST_PYTHON_DECL str(object_cref other);

View File

@@ -16,6 +16,7 @@
#include <boost/detail/binary_search.hpp>
#include <boost/python/self.hpp>
#include <boost/python/dict.hpp>
#include <boost/python/str.hpp>
#include <boost/bind.hpp>
#include <functional>
#include <vector>
@@ -192,16 +193,16 @@ namespace objects
}
static PyGetSetDef instance_getsets[] = {
{"__dict__", instance_get_dict, instance_set_dict, NULL},
{0}
};
static PyGetSetDef instance_getsets[] = {
{"__dict__", instance_get_dict, instance_set_dict, NULL},
{0}
};
static PyMemberDef instance_members[] = {
{"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0},
{0}
};
static PyMemberDef instance_members[] = {
{"__weakref__", T_OBJECT, offsetof(instance<>, weakrefs), 0},
{0}
};
static PyTypeObject class_type_object = {
PyObject_HEAD_INIT(0) //&class_metatype_object)
@@ -275,6 +276,20 @@ static PyMemberDef instance_members[] = {
return 0;
}
object module_prefix()
{
object result(
PyObject_IsInstance(scope().ptr(), upcast<PyObject>(&PyModule_Type))
? object(scope().attr("__name__"))
: api::getattr(scope(), "__module__", str())
);
if (result)
result += '.';
return result;
}
namespace
{
// Find a registered class object corresponding to id. Return a
@@ -303,21 +318,17 @@ static PyMemberDef instance_members[] = {
}
return result;
}
}
// class_base constructor
//
// name - the name of the new Python class
//
// num_types - one more than the number of declared bases
//
// types - array of python::type_info, the first item
// corresponding to the class being created, and the
// rest corresponding to its declared bases.
//
namespace
{
// class_base constructor
//
// name - the name of the new Python class
//
// num_types - one more than the number of declared bases
//
// types - array of python::type_info, the first item
// corresponding to the class being created, and the
// rest corresponding to its declared bases.
//
inline object
new_class(char const* name, std::size_t num_types, class_id const* const types)
{
@@ -336,17 +347,8 @@ static PyMemberDef instance_members[] = {
PyTuple_SET_ITEM(bases.get(), i - 1, upcast<PyObject>(c.release()));
}
object module_name(
PyObject_IsInstance(scope().ptr(), upcast<PyObject>(&PyModule_Type))
? object(scope().attr("__name__"))
: api::getattr(scope(), "__module__", object(""))
);
if (module_name)
module_name += '.';
// Call the class metatype to create a new class
object result = object(class_metatype())(module_name + name, bases, dict());
object result = object(class_metatype())(module_prefix() + name, bases, dict());
assert(PyType_IsSubtype(result.ptr()->ob_type, &PyType_Type));
if (scope().ptr() != Py_None)

View File

@@ -10,6 +10,10 @@ BOOST_PYTHON_DECL detail::new_reference str::call(object const& arg_)
arg_.ptr());
}
BOOST_PYTHON_DECL str::str()
: object(detail::new_reference(PyString_FromString("")))
{}
BOOST_PYTHON_DECL str::str(const char* s)
: object(detail::new_reference(PyString_FromString(s)))
{}

View File

@@ -54,6 +54,7 @@ rule bpl-test ( name ? : files * )
boost-python-runtest $(name) : $(py) <pyd>$(modules) ;
}
bpl-test enum ;
bpl-test minimal ;
bpl-test docstring ;
bpl-test exception_translator ;