Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // https://stackoverflow.com/questions/55052416/how-to-store-class-members-to-be-exposed-to-boost-python
- // Version 1
- // ============================================================================
- #include <boost/format.hpp>
- #include <boost/python.hpp>
- namespace bp = boost::python;
- // ============================================================================
- template <class W>
- class property_def
- {
- public:
- using wrapper_type = bp::class_<W>;
- explicit property_def(std::string name)
- : name_(std::move(name))
- {
- }
- virtual ~property_def() = default;
- void apply(wrapper_type& cls)
- {
- apply_impl(cls, name_);
- }
- private:
- virtual void apply_impl(wrapper_type& cls, std::string const& name) = 0;
- private:
- std::string name_;
- };
- // ----------------------------------------------------------------------------
- template <class W, class D>
- class property_def_impl
- : public property_def<W>
- {
- public:
- using base = property_def<W>;
- using wrapper_type = typename base::wrapper_type;
- property_def_impl(std::string name, D const& d)
- : base(std::move(name))
- , d_(d)
- {
- }
- private:
- void apply_impl(wrapper_type& cls, std::string const& name) override
- {
- cls.def_readonly(name.c_str(), d_);
- }
- private:
- D const& d_;
- };
- // ----------------------------------------------------------------------------
- template <class W>
- class property_collection
- {
- public:
- using class_type = W;
- using property_base = property_def<W>;
- using wrapper_type = typename property_base::wrapper_type;
- using property_base_ptr = std::unique_ptr<property_base>;
- property_collection() = default;
- template <class D>
- void add_readonly(std::string name, D const& d)
- {
- properties_.push_back(std::make_unique<property_def_impl<class_type, D>>(name, d));
- }
- void apply(wrapper_type& cls)
- {
- for (auto& prop : properties_) {
- prop->apply(cls);
- }
- }
- private:
- std::vector<property_base_ptr> properties_;
- };
- // ============================================================================
- struct test_ds
- {
- uint8_t prop0{0};
- uint16_t prop1{1};
- uint32_t prop2{2};
- uint64_t prop3{3};
- float prop4{4.0f};
- double prop5{5.0};
- std::string prop6{"six"};
- static uint8_t prop7;
- };
- uint8_t test_ds::prop7{7};
- // ============================================================================
- BOOST_PYTHON_MODULE(test)
- {
- property_collection<test_ds> p;
- p.add_readonly("prop0", &test_ds::prop0);
- p.add_readonly("prop1", &test_ds::prop1);
- p.add_readonly("prop2", &test_ds::prop2);
- p.add_readonly("prop3", &test_ds::prop3);
- p.add_readonly("prop4", &test_ds::prop4);
- p.add_readonly("prop5", &test_ds::prop5);
- p.add_readonly("prop6", &test_ds::prop6);
- p.add_readonly("prop7", test_ds::prop7);
- bp::class_<test_ds> c("test_ds");
- p.apply(c);
- }
- // ============================================================================
- int main()
- {
- Py_Initialize();
- inittest();
- try {
- bp::object main_module = bp::import("__main__");
- bp::object main_namespace = main_module.attr("__dict__");
- exec(
- "import test\n"
- "o = test.test_ds()\n"
- "print dir(o)\n"
- , main_namespace);
- for (int i(0); i < 8; ++i) {
- exec(str(boost::format("print 'prop%d: ', o.prop%d\n") % i % i).c_str()
- , main_namespace);
- }
- } catch (bp::error_already_set &) {
- PyErr_Print();
- }
- Py_Finalize();
- return 0;
- }
- // ============================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement