test_multiple_inheritance.cpp revision 12037:d28054ac6ec9
112037Sandreas.sandberg@arm.com/*
212037Sandreas.sandberg@arm.com    tests/test_multiple_inheritance.cpp -- multiple inheritance,
312037Sandreas.sandberg@arm.com    implicit MI casts
412037Sandreas.sandberg@arm.com
512037Sandreas.sandberg@arm.com    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
612391Sjason@lowepower.com
712391Sjason@lowepower.com    All rights reserved. Use of this source code is governed by a
812391Sjason@lowepower.com    BSD-style license that can be found in the LICENSE file.
912391Sjason@lowepower.com*/
1012391Sjason@lowepower.com
1112037Sandreas.sandberg@arm.com#include "pybind11_tests.h"
1212037Sandreas.sandberg@arm.com
1312037Sandreas.sandberg@arm.comstruct Base1 {
1412037Sandreas.sandberg@arm.com    Base1(int i) : i(i) { }
1512391Sjason@lowepower.com    int foo() { return i; }
1612391Sjason@lowepower.com    int i;
1712391Sjason@lowepower.com};
1812391Sjason@lowepower.com
1912037Sandreas.sandberg@arm.comstruct Base2 {
2012391Sjason@lowepower.com    Base2(int i) : i(i) { }
2112391Sjason@lowepower.com    int bar() { return i; }
2212391Sjason@lowepower.com    int i;
2312037Sandreas.sandberg@arm.com};
2412037Sandreas.sandberg@arm.com
2512037Sandreas.sandberg@arm.comstruct Base12 : Base1, Base2 {
2612037Sandreas.sandberg@arm.com    Base12(int i, int j) : Base1(i), Base2(j) { }
2712037Sandreas.sandberg@arm.com};
2812037Sandreas.sandberg@arm.com
2912037Sandreas.sandberg@arm.comstruct MIType : Base12 {
3012037Sandreas.sandberg@arm.com    MIType(int i, int j) : Base12(i, j) { }
3112037Sandreas.sandberg@arm.com};
3212037Sandreas.sandberg@arm.com
3312037Sandreas.sandberg@arm.comtest_initializer multiple_inheritance([](py::module &m) {
3412037Sandreas.sandberg@arm.com    py::class_<Base1> b1(m, "Base1");
3512037Sandreas.sandberg@arm.com    b1.def(py::init<int>())
3612037Sandreas.sandberg@arm.com      .def("foo", &Base1::foo);
3712037Sandreas.sandberg@arm.com
3812037Sandreas.sandberg@arm.com    py::class_<Base2> b2(m, "Base2");
3912037Sandreas.sandberg@arm.com    b2.def(py::init<int>())
4012037Sandreas.sandberg@arm.com      .def("bar", &Base2::bar);
4112037Sandreas.sandberg@arm.com
4212037Sandreas.sandberg@arm.com    py::class_<Base12, Base1, Base2>(m, "Base12");
4312037Sandreas.sandberg@arm.com
4412037Sandreas.sandberg@arm.com    py::class_<MIType, Base12>(m, "MIType")
4512037Sandreas.sandberg@arm.com        .def(py::init<int, int>());
4612037Sandreas.sandberg@arm.com
4712037Sandreas.sandberg@arm.com    // Uncommenting this should result in a compile time failure (MI can only be specified via
4812037Sandreas.sandberg@arm.com    // template parameters because pybind has to know the types involved; see discussion in #742 for
4912037Sandreas.sandberg@arm.com    // details).
5012037Sandreas.sandberg@arm.com//    struct Base12v2 : Base1, Base2 {
5112391Sjason@lowepower.com//        Base12v2(int i, int j) : Base1(i), Base2(j) { }
5212391Sjason@lowepower.com//    };
5312037Sandreas.sandberg@arm.com//    py::class_<Base12v2>(m, "Base12v2", b1, b2)
5412391Sjason@lowepower.com//        .def(py::init<int, int>());
5512391Sjason@lowepower.com});
5612037Sandreas.sandberg@arm.com
5712037Sandreas.sandberg@arm.com/* Test the case where not all base classes are specified,
5812037Sandreas.sandberg@arm.com   and where pybind11 requires the py::multiple_inheritance
5912037Sandreas.sandberg@arm.com   flag to perform proper casting between types */
6012391Sjason@lowepower.com
6114299Sbbruce@ucdavis.edustruct Base1a {
6214299Sbbruce@ucdavis.edu    Base1a(int i) : i(i) { }
6314299Sbbruce@ucdavis.edu    int foo() { return i; }
6412037Sandreas.sandberg@arm.com    int i;
6512037Sandreas.sandberg@arm.com};
6612037Sandreas.sandberg@arm.com
6712037Sandreas.sandberg@arm.comstruct Base2a {
6812037Sandreas.sandberg@arm.com    Base2a(int i) : i(i) { }
6912391Sjason@lowepower.com    int bar() { return i; }
7012391Sjason@lowepower.com    int i;
7112391Sjason@lowepower.com};
7212391Sjason@lowepower.com
7312391Sjason@lowepower.comstruct Base12a : Base1a, Base2a {
7412037Sandreas.sandberg@arm.com    Base12a(int i, int j) : Base1a(i), Base2a(j) { }
7512037Sandreas.sandberg@arm.com};
7612037Sandreas.sandberg@arm.com
7712037Sandreas.sandberg@arm.comtest_initializer multiple_inheritance_nonexplicit([](py::module &m) {
7812037Sandreas.sandberg@arm.com    py::class_<Base1a, std::shared_ptr<Base1a>>(m, "Base1a")
7912037Sandreas.sandberg@arm.com        .def(py::init<int>())
8012037Sandreas.sandberg@arm.com        .def("foo", &Base1a::foo);
8112037Sandreas.sandberg@arm.com
8212037Sandreas.sandberg@arm.com    py::class_<Base2a, std::shared_ptr<Base2a>>(m, "Base2a")
8312037Sandreas.sandberg@arm.com        .def(py::init<int>())
8412037Sandreas.sandberg@arm.com        .def("bar", &Base2a::bar);
8512037Sandreas.sandberg@arm.com
8612037Sandreas.sandberg@arm.com    py::class_<Base12a, /* Base1 missing */ Base2a,
8712037Sandreas.sandberg@arm.com               std::shared_ptr<Base12a>>(m, "Base12a", py::multiple_inheritance())
8812037Sandreas.sandberg@arm.com        .def(py::init<int, int>());
8912391Sjason@lowepower.com
9012391Sjason@lowepower.com    m.def("bar_base2a", [](Base2a *b) { return b->bar(); });
9112391Sjason@lowepower.com    m.def("bar_base2a_sharedptr", [](std::shared_ptr<Base2a> b) { return b->bar(); });
9212391Sjason@lowepower.com});
9312037Sandreas.sandberg@arm.com
9412037Sandreas.sandberg@arm.comstruct Vanilla {
9512037Sandreas.sandberg@arm.com    std::string vanilla() { return "Vanilla"; };
9612391Sjason@lowepower.com};
9712391Sjason@lowepower.com
9812037Sandreas.sandberg@arm.comstruct WithStatic1 {
9912037Sandreas.sandberg@arm.com    static std::string static_func1() { return "WithStatic1"; };
10012037Sandreas.sandberg@arm.com    static int static_value1;
10112037Sandreas.sandberg@arm.com};
10212391Sjason@lowepower.com
10312391Sjason@lowepower.comstruct WithStatic2 {
10412391Sjason@lowepower.com    static std::string static_func2() { return "WithStatic2"; };
10512037Sandreas.sandberg@arm.com    static int static_value2;
10612037Sandreas.sandberg@arm.com};
10712037Sandreas.sandberg@arm.com
10812037Sandreas.sandberg@arm.comstruct WithDict { };
10912037Sandreas.sandberg@arm.com
11012037Sandreas.sandberg@arm.comstruct VanillaStaticMix1 : Vanilla, WithStatic1, WithStatic2 {
11112037Sandreas.sandberg@arm.com    static std::string static_func() { return "VanillaStaticMix1"; }
11212037Sandreas.sandberg@arm.com    static int static_value;
11312037Sandreas.sandberg@arm.com};
11412037Sandreas.sandberg@arm.com
11512037Sandreas.sandberg@arm.comstruct VanillaStaticMix2 : WithStatic1, Vanilla, WithStatic2 {
11612037Sandreas.sandberg@arm.com    static std::string static_func() { return "VanillaStaticMix2"; }
11712037Sandreas.sandberg@arm.com    static int static_value;
11812037Sandreas.sandberg@arm.com};
11912037Sandreas.sandberg@arm.com
12012037Sandreas.sandberg@arm.comstruct VanillaDictMix1 : Vanilla, WithDict { };
12112037Sandreas.sandberg@arm.comstruct VanillaDictMix2 : WithDict, Vanilla { };
12212391Sjason@lowepower.com
12312391Sjason@lowepower.comint WithStatic1::static_value1 = 1;
12412391Sjason@lowepower.comint WithStatic2::static_value2 = 2;
12512037Sandreas.sandberg@arm.comint VanillaStaticMix1::static_value = 12;
12612037Sandreas.sandberg@arm.comint VanillaStaticMix2::static_value = 12;
12712391Sjason@lowepower.com
12812391Sjason@lowepower.comtest_initializer mi_static_properties([](py::module &pm) {
12912037Sandreas.sandberg@arm.com    auto m = pm.def_submodule("mi");
13012037Sandreas.sandberg@arm.com
13112037Sandreas.sandberg@arm.com    py::class_<Vanilla>(m, "Vanilla")
13212037Sandreas.sandberg@arm.com        .def(py::init<>())
13312391Sjason@lowepower.com        .def("vanilla", &Vanilla::vanilla);
13412391Sjason@lowepower.com
13512391Sjason@lowepower.com    py::class_<WithStatic1>(m, "WithStatic1")
13612037Sandreas.sandberg@arm.com        .def(py::init<>())
13712037Sandreas.sandberg@arm.com        .def_static("static_func1", &WithStatic1::static_func1)
13812037Sandreas.sandberg@arm.com        .def_readwrite_static("static_value1", &WithStatic1::static_value1);
13912037Sandreas.sandberg@arm.com
14012037Sandreas.sandberg@arm.com    py::class_<WithStatic2>(m, "WithStatic2")
14112037Sandreas.sandberg@arm.com        .def(py::init<>())
14212037Sandreas.sandberg@arm.com        .def_static("static_func2", &WithStatic2::static_func2)
14312037Sandreas.sandberg@arm.com        .def_readwrite_static("static_value2", &WithStatic2::static_value2);
14412037Sandreas.sandberg@arm.com
14512037Sandreas.sandberg@arm.com    py::class_<VanillaStaticMix1, Vanilla, WithStatic1, WithStatic2>(
14612037Sandreas.sandberg@arm.com        m, "VanillaStaticMix1")
14712037Sandreas.sandberg@arm.com        .def(py::init<>())
14812037Sandreas.sandberg@arm.com        .def_static("static_func", &VanillaStaticMix1::static_func)
14912037Sandreas.sandberg@arm.com        .def_readwrite_static("static_value", &VanillaStaticMix1::static_value);
15012037Sandreas.sandberg@arm.com
15112037Sandreas.sandberg@arm.com    py::class_<VanillaStaticMix2, WithStatic1, Vanilla, WithStatic2>(
15212391Sjason@lowepower.com        m, "VanillaStaticMix2")
15312391Sjason@lowepower.com        .def(py::init<>())
15412037Sandreas.sandberg@arm.com        .def_static("static_func", &VanillaStaticMix2::static_func)
15512037Sandreas.sandberg@arm.com        .def_readwrite_static("static_value", &VanillaStaticMix2::static_value);
15612037Sandreas.sandberg@arm.com
15712037Sandreas.sandberg@arm.com#if !defined(PYPY_VERSION)
15812037Sandreas.sandberg@arm.com    py::class_<WithDict>(m, "WithDict", py::dynamic_attr()).def(py::init<>());
15912037Sandreas.sandberg@arm.com    py::class_<VanillaDictMix1, Vanilla, WithDict>(m, "VanillaDictMix1").def(py::init<>());
16012037Sandreas.sandberg@arm.com    py::class_<VanillaDictMix2, WithDict, Vanilla>(m, "VanillaDictMix2").def(py::init<>());
16112391Sjason@lowepower.com#endif
16212037Sandreas.sandberg@arm.com});
16312037Sandreas.sandberg@arm.com