• Jason Rhinelander's avatar
    Support multiple inheritance from python · e45c2114
    Jason Rhinelander authored
    This commit allows multiple inheritance of pybind11 classes from
    Python, e.g.
    
        class MyType(Base1, Base2):
            def __init__(self):
                Base1.__init__(self)
                Base2.__init__(self)
    
    where Base1 and Base2 are pybind11-exported classes.
    
    This requires collapsing the various builtin base objects
    (pybind11_object_56, ...) introduced in 2.1 into a single
    pybind11_object of a fixed size; this fixed size object allocates enough
    space to contain either a simple object (one base class & small* holder
    instance), or a pointer to a new allocation that can contain an
    arbitrary number of base classes and holders, with holder size
    unrestricted.
    
    * "small" here means having a sizeof() of at most 2 pointers, which is
    enough to fit unique_ptr (sizeof is 1 ptr) and shared_ptr (sizeof is 2
    ptrs).
    
    To minimize the performance impact, this repurposes
    `internals::registered_types_py` to store a vector of pybind-registered
    base types.  For direct-use pybind types (e.g. the `PyA` for a C++ `A`)
    this is simply storing the same thing as before, but now in a vector;
    for Python-side inherited types, the map lets us avoid having to do a
    base class traversal as long as we've seen the class before.  The
    change to vector is needed for multiple inheritance: Python types
    inheriting from multiple registered bases have one entry per base.
    e45c2114
test_multiple_inheritance.cpp 7.67 KB