@@ -48,9 +48,11 @@ class G3PythonInterpreter {
4848// pybind11 compatibility functions
4949namespace boost { namespace python {
5050
51+ namespace detail {
52+
5153// template magic to collect all the py::arg()'s into one object for boost
5254template <typename ... Args>
53- auto reorder_keywords (Args&&... args) {
55+ auto extract_keywords (Args&&... args) {
5456 using T = py::detail::keywords<1 >;
5557
5658 auto extra = std::tuple_cat (
@@ -75,7 +77,9 @@ auto reorder_keywords(Args&&... args) {
7577 return detail::keywords<sizeof ...(kw)>{kw...};
7678 }, kwargs);
7779
78- return std::tuple_cat (extra, std::make_tuple (kwds));
80+ return std::pair (extra, std::move (kwds));
81+ }
82+
7983}
8084
8185class module_ : public scope
@@ -87,11 +91,152 @@ class module_ : public scope
8791
8892 py::object def_submodule (const std::string &name);
8993
94+ template <typename Func>
95+ void def (const char *name, Func && fn) {
96+ py::def (name, std::forward<Func>(fn));
97+ }
98+
99+ template <typename Func>
100+ void def (const char *name, Func && fn, const char *doc) {
101+ py::def (name, std::forward<Func>(fn), doc);
102+ }
103+
104+ template <size_t N, typename Func>
105+ void def (const char *name, Func && fn, py::detail::keywords<N> args, const char *doc) {
106+ py::def (name, std::forward<Func>(fn), args, doc);
107+ }
108+
109+ template <typename Func, typename ... Args>
110+ void def (const char *name, Func && fn, Args &&... args) {
111+ auto [extra, kwargs] = py::detail::extract_keywords (std::forward<Args>(args)...);
112+ std::apply ([&, &kw=kwargs](auto &&... a) {
113+ py::def (name, std::forward<Func>(fn), kw, a...);
114+ }, extra);
115+ }
116+ };
117+
118+ // class with pybind11-like functions
119+ template <typename ...T>
120+ class compat_class_
121+ {
122+ public:
123+ typedef compat_class_<T...> self;
124+
125+ compat_class_ (const char *name, const char *docstring = 0 )
126+ : cls_(name, docstring, py::no_init) {};
127+
128+ auto ptr () { return cls_.ptr (); }
129+
130+ template <typename ... Args>
131+ self& add_property (Args &&... args) {
132+ cls_.add_property (std::forward<Args>(args)...);
133+ return *this ;
134+ }
135+
136+ template <typename ... Args>
137+ self& add_static_property (Args &&... args) {
138+ cls_.add_static_property (std::forward<Args>(args)...);
139+ return *this ;
140+ }
141+
142+ template <typename ... Args>
143+ self& def_property (const char *name, Args &&... args) {
144+ cls_.add_property (name, std::forward<Args>(args)...);
145+ return *this ;
146+ }
147+
148+ template <typename ... Args>
149+ self& def_property_readonly (const char *name, Args &&... args) {
150+ cls_.add_property (name, std::forward<Args>(args)...);
151+ return *this ;
152+ }
153+
90154 template <typename ... Args>
91- auto def (Args&&... args) {
92- std::apply ([](auto &&... a) { py::def (a...); },
93- reorder_keywords (args...));
155+ self& def_readwrite (Args &&... args) {
156+ cls_.def_readwrite (std::forward<Args>(args)...);
157+ return *this ;
158+ }
159+
160+ template <typename ... Args>
161+ self& def_readonly (Args &&... args) {
162+ cls_.def_readonly (std::forward<Args>(args)...);
163+ return *this ;
164+ }
165+
166+ template <typename P>
167+ self& def_pickle (P && p) {
168+ cls_.def_pickle (p);
169+ return *this ;
170+ }
171+
172+ self& staticmethod (const char *name) { cls_.staticmethod (name); return *this ; }
173+
174+ template <typename Func>
175+ self& def (const char *name, Func && fn) {
176+ cls_.def (name, std::forward<Func>(fn));
177+ return *this ;
178+ }
179+
180+ template <typename Func>
181+ self& def (const char *name, Func && fn, const char *doc) {
182+ cls_.def (name, std::forward<Func>(fn), doc);
183+ return *this ;
184+ }
185+
186+ template <size_t N, typename Func>
187+ self& def (const char *name, Func && fn, py::detail::keywords<N> args, const char *doc = 0 ) {
188+ cls_.def (name, std::forward<Func>(fn), args, doc);
189+ return *this ;
94190 }
191+
192+ template <typename Func, typename ... Args>
193+ self& def (const char *name, Func && fn, Args && ... args) {
194+ if (sizeof ...(args) == 0 ) {
195+ cls_.def (name, std::forward<Func>(fn));
196+ return *this ;
197+ }
198+ auto [extra, kwargs] = py::detail::extract_keywords (std::forward<Args>(args)...);
199+ std::apply ([&, &kw=kwargs](auto &&... a) {
200+ cls_.def (name, std::forward<Func>(fn), kw, a...);
201+ }, extra);
202+ return *this ;
203+ }
204+
205+ template <class V >
206+ self& def (const def_visitor<V> &visitor) {
207+ cls_.def (visitor);
208+ return *this ;
209+ }
210+
211+ template <typename ... InitArgs, typename ... Args>
212+ self& def (const py::init<InitArgs...> &initf, Args &&... args) {
213+ if (sizeof ...(args) == 0 ) {
214+ cls_.def (initf);
215+ return *this ;
216+ }
217+ auto [extra, kwargs] = py::detail::extract_keywords (std::forward<Args>(args)...);
218+ auto vis = std::apply ([&, &kw=kwargs](auto &&... a) {
219+ return py::init<InitArgs...>(kw, a...);
220+ }, extra);
221+ cls_.def (vis);
222+ return *this ;
223+ }
224+
225+ template <typename ... Args>
226+ self& def_static (const char *name, Args &&... args) {
227+ this ->def (name, std::forward<Args>(args)...);
228+ cls_.staticmethod (name);
229+ return *this ;
230+ }
231+
232+ self& def_buffer (PyBufferProcs &p) {
233+ PyTypeObject *obj = (PyTypeObject *)cls_.ptr ();
234+ obj->tp_as_buffer = &p;
235+ return *this ;
236+ }
237+
238+ private:
239+ py::class_<T...> cls_;
95240};
96241
97242class gil_scoped_release : public G3PythonContext
0 commit comments