How to control argument passing policy in pybind11 wrapping of std::function? - pybind11

I have a class in c++ that I'm wrapping into python with pybind11. That class has a std::function, and I'd like to control how the arguments to that function are dealt with (like return value policies). I just can't find the syntax or examples to do this...
class N {
public:
using CallbackType = std::function<void(const OtherClass*)>;
N(CallbackType callback): callback(callback) { }
CallbackType callback;
void doit() {
OtherClass * o = new OtherClass();
callback(o);
}
}
wrapped with
py::class_<OtherClass>(...standard stuff...);
py::class_<N>(m, "N")
.def(py::init<N::CallbackType>(),
py::arg("callback"));
I all works: I can do this in python:
def callback(o):
dosomethingwith(o)
k = N(callback)
, but I'd like to be able to control what happens when callback(o); is called - whether python then will take ownership of the wrapped o variable or not, basically.
I put a printout in the destructor of OtherClass, and as far as I can tell, it never gets called.

OK, I think I figured it out:
Instead of std::function, use a pybind11::function:
using CallbackType = pybind11::function
and then
void doit(const OtherClass &input) {
if (<I want to copy it>) {
callback(pybind11::cast(input, pybind11::return_value_policy::copy));
} else {
callback(pybind11::cast(input, pybind11::return_value_policy::reference));
}
}

I see nothing in pybind11/functional that allows you to change the ownership of the parameters at the point of call, as the struct func_wrapper used is function local, so can not be specialized. You could provide another wrapper yourself, but in the code you can't know whether the callback is a Python function or a bound C++ function (well, technically you can if that bound C++ function is bound by pybind11, but you can't know in general). If the function is C++, then changing Python ownership in the wrapper would be the wrong thing to do, as the temporary proxy may destroy the object even as its payload is stored by the C++ callback.
Do you have control over the implementation of class N? The reason is that by using std::shared_ptr all your ownership problems will automagically evaporate, regardless of whether the callback function is C++ or Python and whether it stores the argument or not. Would work like so, expanding on your example above:
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
namespace py = pybind11;
class OtherClass {};
class N {
public:
using CallbackType = std::function<void(const std::shared_ptr<OtherClass>&)>;
N(CallbackType callback): callback(callback) { }
CallbackType callback;
void doit() {
auto o = std::make_shared<OtherClass>();
callback(o);
}
};
PYBIND11_MODULE(example, m) {
py::class_<OtherClass, std::shared_ptr<OtherClass>>(m, "OtherClass");
py::class_<N>(m, "N")
.def(py::init<N::CallbackType>(), py::arg("callback"))
.def("doit", &N::doit);
}

Related

AngelScript - Avoid implicit default constructor from running

I'm currently testing some simple AngelScript stuff, and noticed something I find a bit strange when it comes to how objects are initialized from classes.
Let's say I define a class like this:
class MyClass {
int i;
MyClass(int i) {
this.i = i;
}
}
I can create an object of this class by doing this:
MyClass obj = MyClass(5);
However it seems I can also create an object by doing this:
MyClass obj;
The problem here is that obj.i becomes a default value as it is undefined.
Additionally, adding a default constructor to my class and a print function call in each one reveals that when I do MyClass obj = MyClass(5); BOTH constructors are called, not just the one with the matching parameter. This seems risky to me, as it could initialize a lot of properties unnecessarily for this "ghost" instance.
I can avoid this double-initialization by using a handle, but this seems more like a work-around rather than a solution:
MyClass# obj = MyClass(5);
So my question sums up to:
Can I require a specific constructor to be called?
Can I prevent a default constructor from running?
What's the proper way to deal with required parameters when creating objects?
Mind that this is purely in the AngelScript script language, completely separate from the C++ code of the host application. The host is from 2010 and is not open-source, and my knowledge of their implementation is very limited, so if the issue lies there, I can't change it.
In order to declare class and send the value you choose to constructor try:
MyClass obj(5);
To prevent using default constructor create it and use:
.
MyClass()
{
abort("Trying to create uninitialized object of type that require init parameters");
}
or
{
exit(1);
}
or
{
assert(1>2,"Trying to create uninitialized object of type that require init parameters");
}
or
{
engine.Exit();
}
in case that any of those is working in you environment.
declaring the constructor as private seems not to work in AS, unlike other languages.

Is it possible to use template arguments in virtual function in modern C++?

I used to do C++ development several years ago and back then I found it difficult to combine template programming with OOP. Currently I program in Swift and I tried doing some of the things I struggled with then.
This Swift code will illustrate the problem:
// protocol is like Java interface or C++ pure virtual base class
protocol Log {
// want to able to add elements from a collection of Ints, but
// it should be any sort of collection that
// can be treated as a sequence
func add<T: SequenceType where T.Generator.Element == Int>(values: T)
}
class DiscreteLog: Log {
var vals: [Int] = []
func add<T: SequenceType where T.Generator.Element == Int>(values: T) {
for v in values {
vals.append(v)
}
}
}
class ContinousLog: Log {
var vals: [Double] = []
func add<T: SequenceType where T.Generator.Element == Int>(values: T) {
for v in values {
vals.append(Double(v))
}
}
}
// I don't have to know whether the log is Continuous or Discrete
// I can still add elements to it
var log: Log = ContinousLog()
log.add([1, 2, 3])
// and elements can come from any kind of sequence, it does not need
// to be an array
log.add(["four": 4, "five: 5].values)
So the problem is that if the C++ code defined as as:
virtual void add(vector<Int> elements>)
Then sure I could have multiple subclasses implement this method, but I could never provide anything but vectors as arguments.
I could try changing it to something more generic using iterator:
virtual void add(vector<Int>::iterator elements>)
But I am still limited to using vector iterators. So I guess I would have to write something like:
template<typename Iterator>
virtual void add(Iterator elements>)
But that will give compile errors as template based arguments are not allowed for virtual methods.
Anyway I wondered if this sort of thing is possible in modern C++.
C++ templates and C#/Swift/Java generics are different things.
They are both "pattern code" in a sense (they are patterns that generate code), but C#/Swift/Java generics use type erasure and "forget" almost everything about the types they work with, while C++ templates are elephants. And elephants never forget.
It turns out that can make an elephant forget, but you have to tell it to. The technique of "forgetting" about details of a type is known as "type erasure" or "run time concepts".
So you want to type erase down to the concept of "a sequence of integers". You want to take any type, so long as it is a sequence of integers, and be able to iterate over it. Seems fair.
boost has such type erasures. But who wants to always rely on boost?
First, type erase an input iterator:
template<class T>
struct input_iterator:
std::iterator<
std::input_iterator_tag, // category
T, // value
std::ptrdiff_t, // distance
T*, // pointer
T // reference
>
{
struct erase {
virtual void advance() = 0;
virtual erase* clone() const = 0;
virtual T get() const = 0;
virtual bool equal(erase const& o) = 0;
virtual ~erase() {}
};
std::unique_ptr<erase> pimpl;
input_iterator(input_iterator&&)=default;
input_iterator& operator=(input_iterator&&)=default;
input_iterator()=default;
input_iterator& operator++() {
pimpl->advance();
return *this;
}
input_iterator operator++(int) {
auto copy = *this;
++*this;
return copy;
}
input_iterator(input_iterator const& o):
pimpl(o.pimpl?o.pimpl->clone():nullptr)
{}
input_iterator& operator=(input_iterator const&o) {
if (!o.pimpl) {
if (pimpl) pimpl->reset();
return *this;
}
pimpl = std::unique_ptr<erase>(o.pimpl->clone());
return *this;
}
T operator*() const {
return pimpl->get();
}
friend bool operator==( input_iterator const& lhs, input_iterator const& rhs ) {
return lhs.pimpl->equal(*rhs.pimpl);
}
friend bool operator!=( input_iterator const& lhs, input_iterator const& rhs ) {
return !(lhs==rhs);
}
template<class It>
struct impl:erase{
It it;
impl(impl const&)=default;
impl(It in):it(std::move(in)){}
virtual void advance() override { ++it; }
virtual erase* clone() const override { return new impl(*this); }
virtual T get() const override { return *it; }
virtual bool equal(erase const& o) override {
return static_cast<impl const&>(o).it == it;
}
};
template<
class It,
class=std::enable_if<
std::is_convertible<
typename std::iterator_traits<It>::reference,
T
>{}
>
>
input_iterator(It it):pimpl( new impl<It>{it} ) {}
}; // input_iterator
Next, have a range template. This is a container that stores non-type erased iterators, and exposes enough to iterate over those iterators.
template<class It>
struct range {
It b; It e;
It begin() const { return b; }
It end() const { return e; }
range() = default;
range(It start, It finish):b(std::move(start)),e(std::move(finish)) {};
range(range&&)=default;
range(range const&)=default;
range& operator=(range&&)=default;
range& operator=(range const&)=default;
template<class R,
class R_It=std::decay_t<decltype(std::begin(std::declval<R>()))>,
class=std::enable_if< std::is_convertible<R_It, It>{} >
>
range( R&& r ):
range(std::begin(r), std::end(r))
{} // TODO: enable ADL begin lookup
};
The above type is really basic: C++1z has better ones, as does boost, as do I have in my own code base. But it is enough to handle for(:) loops, and implicit conversion from containers with compatible iterators.
Finally our sequence type:
template<class T>
using sequence_of = range<input_iterator<T>>;
Wait, that's it? Nice, those types compose well!
And barring errors, we are done.
Your code now would take a sequence_of<int>, and they could pass a std::vector<int> or std::list<int> or whatever.
The input_iterator type-erasure type-erases any iterator down to getting a T via *, ==, copy, and ++ advance, which is enough for a for(:) loop.
The range<input_iterator<int>> will accept any iterable range (including containers) whose iterators can be converted to an input_iterator<int>.
The downside? We just introduced a bunch of overhead. Each method goes through virtual dispatch, from ++ to * to ==.
This is (roughly) what generics do -- they type-erase down to the requirements you give it in the generic clause. This means they are working with abstract objects, not concrete objects, so they unavoidably suffer performance penalties of this indirection.
C++ templates can be used to generate type erasure, and there are even tools (boost has some) to make it easier. What I did above is a half-assed manual one. Similar techniques are used in std::function<R(Args...)>, which type-erases down to (conceptually) {copy, call with (Args...) returning R, destroy} (plus some incidentals).
live example.
(The code above freely uses C++14.)
So the C++ equivalent Log is:
struct Log {
virtual void add(sequence_of<int>) = 0;
virtual ~Log() {}
};
Now, the type erasure code above is a bit ugly. To be fair, I just implemented a language feature in C++ without direct language support for it.
I've seen some proposals to make type erasure easier in C++. I do not know the status of those proposals.
If you want to do your own, here is an "easy" way to do type erasure in 3 steps:
First, determine what operations you want to erase. Write the equivalent of input_iterator<T> -- give it a bunch of methods and operators that do what you want. Be sparse. Call this the "external type". Ideally nothing in this type is virtual, and it should be a Regular or Semi-regular type (ie, it should behave value-like, or move-only-value-like). Don't implement anything but the interface yet.
Second, write an inner class erase. It provides a pure-virtual interface to a set of functions that could provide what you need in your external type.
Store a unique_ptr<erase> pimpl; within the external type. Forward the methods you expose in the external type to the pimpl;.
Third, write an inner template<class X> class impl<X>:erase. It stores a variable X x;, and it implements everything in erase by interacting with X. It should be constructable from an X (with optional perfect forwarding).
You then create a perfect forwarding constructor for the external type that creates its pimpl via a new impl<X>(whatever). Ideally it should check that its argument is a valid one via SFINAE techniques, but that is just a qualify of implementation issue.
Now the external type "erases" the type of any object it is constructed from "down to" the operations you exposed.
Now, for your actual problem, I'd write array_view or steal std::experimental::array_view, and restrict my input to be any kind of contiguous buffer of data of that type. This is more performant, and accepting any sequence is over engineering unless you really need it.

How to avoid interface method implementations that needs a pointer receiver?

Consider the following example: http://play.golang.org/p/eAot_sVwND
package main
import "fmt"
type Incrementor interface {
Increment()
}
type Counter struct {
i int
Incrementor
}
func (c *Counter) Increment(){
c.i++
}
func main() {
var c Incrementor
c = &Counter{}
c.Increment()
fmt.Println(c)
}
Unfortunatelly I need to c = &Counter{} because Counter.Increment() implementation has a pointer receiver otherwise c.Increment() calls won't be able to modify c.x property:
func (c Counter) Increment(){
c.i++ // no errors, but now we increment c.x having a copy of c as context
}
How to make original implementation works without & on c = &Counter{}? In other words, how to avoid the need for the pointer receiver on C.Increment implementation at all?
This is just a nit, but I think that maybe a pointer is not necessary to do that in Go.
This is just a nit, but I think that maybe a pointer is not necessary to do that in Go.
Considering that Go uses to pass everything by value, a pointer receiver is the natural way to achieve what you want.
This is supported by the Go FAQ:
First, and most important, does the method need to modify the receiver? If it does, the receiver must be a pointer.
You would find a similar conclusion in "Things I Wish Someone Had Told Me About Golang: pointers"
You could consider defining an NewCounter function that encapsulates the initialization of your type (or some 3rd party) and returns a *Counter. Usage could look something like this:
func main() {
c := NewCounter()
c.Increment()
fmt.Println(c)
}

struct vs class for writing D wrappers around foreign languages

(note: this is related to Usage preference between a struct and a class in D language but for a more specific use case)
When writing a D interface to, say, C++ code, SWIG and others do something like this:
class A{
private _A*ptr;//defined as extern(C) elsewhere
this(){ptr=_A_new();}//ditto
this(string s){ptr=_A_new(s);} //ditto
~this(){_A_delete(ptr);} //ditto
void fun(){_A_fun(ptr);}
}
Let's assume no inheritance is needed.
My question is: wouldn't it be preferable to use a struct instead of a class for this?
The pros being:
1) efficiency (stack allocation)
2) ease-of-use (no need to write new everywhere, eg: auto a=A(B(1),C(2)) vs auto a=new A(new B(1),new C(2)) )?
The cons being:
require additional field is_own to handle aliasing via postblit.
What would be the best way to do so?
Is there anything else to worry about?
Here's an attempt:
struct A{
private _A*ptr;
bool is_own;//required for postblit
static A opCall(){//cannot write this() for struct
A a;
a.ptr=_A_new();
a.is_own=true;
return a;
}
this(string s){ptr=_A_new(s); is_own=true;}
~this(){if(is_own) _A_delete(ptr);}
void fun(){_A_fun(ptr);}
this(this){//postblit;
//shallow copy: I don't want to call the C++ copy constructor (expensive or unknown semantics)
is_own=false; //to avoid _A_delete(ptr)
}
}
Note the postblit is necessary for cases when calling functions such as:
myfun(A a){}
I suggest that you read this page. The only functions on C++ classes that you can call in D are virtual functions. That means that
D can­not call C++ spe­cial mem­ber func­tions, and vice versa. These in­clude con­struc­tors, de­struc­tors, con­ver­sion op­er­a­tors, op­er­a­tor over­load­ing, and al­lo­ca­tors.
And when you declare a C++ class in D, you use an extern(C++) interface. So, your class/struct would look like this
extern(C++) interface A
{
void fun();
}
However, you'd need another extern(C++) function to allocate any objects of type A, since it's C++ code that has to do that as the D code doesn't have access to any of the constructors. You'd also need a way to pass it back to C++ code to be deleted when you're done with it.
Now, if you want to wrap that interface in a type which is going to call the extern(C++) function to construct it and the extern(C++) function to delete it (so that you don't have to worry about doing that manually), then whether you use a class or struct depends entirely on what you're trying to do with it.
A class would be a reference type, which mirrors what the C++ class actually is. So, passing it around would work without you having to do anything special. But if you wanted a guarantee that the wrapped C++ object was freed, you'd have to do so manually, because there's no guarantee that the D class' finalizer would ever be run (and presumably, that's where you'd put the code for calling the C++ function to delete the C++ object). You'd have to either use clear (which will actually be renamed to destroy in the next release of the compiler - dmd 2.060) to destroy the D object (i.e. call its finalizer and handle the destruction of any of its member variables which are value types), or you'd have to call a function on the D object which called the C++ function to delete the C++ object. e.g.
extern(C++) interface A
{
void fun();
}
extern(C++) A createA();
extern(C++) void deleteA(A a);
class Wrapper
{
public:
this()
{
_a = createA();
}
~this()
{
deleteA(_a);
}
auto opDispatch(string name, Args...)(Args args)
{
return mixin("_a." ~ name ~ "(args)");
}
private:
A _a;
}
void main()
{
auto wrapped = new Wrapper();
//do stuff...
//current
clear(wrapped);
//starting with dmd 2.060
//destroy(wrapped);
}
But that does have the downside that if you don't call clear/destroy, and the garbage collector never collects your wrapper object, deleteA will never be called on the C++ object. That may or may not matter. It depends on whether the C++ object really needs its destructor to be called before the program terminates or whether it can just let its memory return to the OS (without its destructor being called) when the program terminates if the GC never needs to collect the wrapper object.
If you want deterministic destruction, then you need a struct. That means that you'll need to worry about making the struct into a reference type. Otherwise, if it gets copied, when one of them is destroyed, the C++ object will be deleted, and the other struct will point to garbage (which it will then try and delete when it gets destroyed). To solve that, you could use std.typecons.RefCounted. Then you get something like
extern(C++) interface A
{
void fun();
}
extern(C++) A createA();
extern(C++) void deleteA(A a);
struct Wrapper
{
public:
static Wrapper opCall()
{
Wrapper retval;
retval._a = createA();
return retval;
}
~this()
{
if(_a !is null)
{
deleteA(_a);
_a = null;
}
}
auto opDispatch(string name, Args...)(Args args)
{
return mixin("_a." ~ name ~ "(args)");
}
private:
A _a;
}
void main()
{
auto wrapped = RefCounted!Wrapper();
//do stuff...
}
You could also define the wrapper so that it has the ref-counting logic in it and avoid RefCounted, but that would definitely be more complicated.
Regardless, I would definitely advise against your suggestion of using a bool to mark whether the wrapper owns the C++ object or not, because if the original wrapper object gets destroyed before all of the copies do, then your copies will point to garbage.
Another option if you did want the C++ object's copy constructor to be used (and therefore treat the C++ object as a value type) would be to add an extern(C++) function which took the C++ object and returned a copy of it and then use it in a postblit.
extern(C++) A copyA(A a);
this(this)
{
if(_a !is null)
_a = copyA(a);
}
Hopefully that makes things clear enough.

Timer Thread with passed Function* and Param

I'm working on finishing up my server for my first iPhone application, and I want to implement a simple little feature.
I would like to run a function (perhaps method as well), if another function returns a certain value after a certain waiting period. Fairly simple concept.... right?
Here's my basic foundation.
template <typename T,class TYP>
struct funcpar{
T (*function)(TYP);
TYP parameter;
funcpar(T (*func)(TYP),TYP param);
funcpar& operator=(const funcpar& fp);
};
The goal here is to be able to call funcpar::function(funcpar::parameter) to run the stored function and parameter, and not have to worry about anything else...
When I attempted to use a void* parameter instead of the template, I couldn't copy the memory as an object (because I didn't know what the end object was going to be, or the beginning for that matter) and when I tried multiple timers, every single object's parameter would change to the new parameter passed to the new timer... With the previous struct I have a
question:
Is it possible to make an all-inclusive pointer to this type of object inside a method of a class? Can I templatize a method, and not the whole class? Would it work exactly like a function template?
I have a managing class that holds a vector of these "jobs" and takes care of everything fairly well. I just don't know how to use a templatized function with the struct, or how to utilize templates on a single method in a class..
I'm also utilizing this in my custom simple threadpool, and that's working fairly well, and has the same problems...
I have another question:
Can I possibly store a function with a parameter before it's run? Something like toRun = dontrunmeyet(withThisParameter);? Is my struct even necessary?
Am I going about this whole thing incorrectly?
If this is overly ambiguous, I can set you up with my whole code for context
In order to create a class method that takes a template parameter, yes, it would work almost exactly like a function template. For example:
class A
{
public:
template<typename T>
void my_function(const T& value) { }
};
int main()
{
A test;
test.my_function(5);
return 0;
}
Secondly, for your structure, you can actually turn that into a functor-object that by overloading operator(), lets you call the structure as-if it were a function rather than having to actually call the specific function pointer members inside the structure. For instance, your structure could be re-written to look like this:
#include <iostream>
template <class ReturnType, class ParameterType>
class funcpar
{
private:
ReturnType (*function)(ParameterType);
ParameterType parameter;
public:
funcpar(ReturnType (*func)(ParameterType),ParameterType param):
function(func), parameter(param) {}
funcpar& operator=(const funcpar& fp);
//operator() overloaded to be a function that takes no arguments
//and returns type ReturnType
ReturnType operator() ()
{
return function(parameter);
}
};
int sample_func(int value)
{
return value + 1;
}
int main()
{
funcpar<int, int> test_functor(sample_func, 5);
//you can call any instance of funcpar just like a normal function
std::cout << test_functor() << std::endl;
return 0;
}
BTW, you do need the functor object (or your structure, etc.) in order to bind a dynamic parameter to a function before the function is called in C/C++ ... you can't "store" a parameter with an actual function. Binding a parameter to a function is actually called a closure, and in C/C++, creating a closure requires a structure/class or some type of associated data-structure you can use to bind a function with a specific parameter stored in memory that is used only for a specific instance of that function call.