Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class-scoped enum

I have a c++ class with an enum inside, and I wanted to mimick that with boost::python, so that I can write MyClass.value in python. boost::python::class_ does not have an enum_ method, and I was looking for workarounds.

  1. I first tried with lambdas like

    MyClass{
        enum{value1,value2};
    };
    
    class_<MyClass>("MyClass").add_property("value1",&[](){return value1;}).staticmethod("value1");
    

    which gives compiler error (in get_signature for add_property). I know I could create getter method for each of the values, but that seems very awkward to me (typing-wise).

  2. Using attr:

    auto classObj=class_<MyClass>("MyClass");
    classObj.attr("value1")=(int)value1;
    classObj.attr("value2")=(int)value2;
    

    but it cannot be chained like .def and other methods returning reference to the instance.

Is there a more elegant solution?

like image 814
eudoxos Avatar asked Aug 31 '11 07:08

eudoxos


1 Answers

You can do it using a scope:

#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/scope.hpp>
#include <boost/python/enum.hpp>

namespace bp = boost::python;

class MyClass{
    public:
        enum MyEnum {value1,value2};
};

BOOST_PYTHON_MODULE(nestedtest){

    bp::scope the_scope
        = bp::class_<MyClass>("MyClass")
        ;

    bp::enum_<MyClass::MyEnum>("MyEnum")
        .value("value1", MyClass::value1)
        .value("value2", MyClass::value2)
        .export_values()
        ;
}

Then in python, your enum values are:

In [8]: nestedtest.MyClass.MyEnum.values
Out[8]: {0: nestedtest.MyEnum.value1, 1: nestedtest.MyEnum.value2}

In [9]: nestedtest.MyClass.MyEnum.value1
Out[9]: nestedtest.MyEnum.value1

In [10]: nestedtest.MyClass.MyEnum.value2
Out[10]: nestedtest.MyEnum.value2

(from my ipython shell, I tested this and all ;)

like image 95
James Avatar answered Sep 26 '22 01:09

James