mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 14:45:12 +00:00
In def_readonly and def_readwrite, there is an assertion that the member comes from the class or a base class: static_assert(std::is_base_of<C, type>::value, "..."); However, if C and type are the same type, is_base_of will still only be true if they are the same _non-union_ type. This means we can't define accessors for the members of a union type because of this assertion. Update the assertion to test std::is_same<C, type>::value || std::is_base_of<C, type>::value which will allow union types, or members of base classes. Also add a basic unit test for accessing unions.
This commit is contained in:
parent
0071a3feb0
commit
1aa8dd1745
@ -1185,7 +1185,7 @@ public:
|
|||||||
|
|
||||||
template <typename C, typename D, typename... Extra>
|
template <typename C, typename D, typename... Extra>
|
||||||
class_ &def_readwrite(const char *name, D C::*pm, const Extra&... extra) {
|
class_ &def_readwrite(const char *name, D C::*pm, const Extra&... extra) {
|
||||||
static_assert(std::is_base_of<C, type>::value, "def_readwrite() requires a class member (or base class member)");
|
static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value, "def_readwrite() requires a class member (or base class member)");
|
||||||
cpp_function fget([pm](const type &c) -> const D &{ return c.*pm; }, is_method(*this)),
|
cpp_function fget([pm](const type &c) -> const D &{ return c.*pm; }, is_method(*this)),
|
||||||
fset([pm](type &c, const D &value) { c.*pm = value; }, is_method(*this));
|
fset([pm](type &c, const D &value) { c.*pm = value; }, is_method(*this));
|
||||||
def_property(name, fget, fset, return_value_policy::reference_internal, extra...);
|
def_property(name, fget, fset, return_value_policy::reference_internal, extra...);
|
||||||
@ -1194,7 +1194,7 @@ public:
|
|||||||
|
|
||||||
template <typename C, typename D, typename... Extra>
|
template <typename C, typename D, typename... Extra>
|
||||||
class_ &def_readonly(const char *name, const D C::*pm, const Extra& ...extra) {
|
class_ &def_readonly(const char *name, const D C::*pm, const Extra& ...extra) {
|
||||||
static_assert(std::is_base_of<C, type>::value, "def_readonly() requires a class member (or base class member)");
|
static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value, "def_readonly() requires a class member (or base class member)");
|
||||||
cpp_function fget([pm](const type &c) -> const D &{ return c.*pm; }, is_method(*this));
|
cpp_function fget([pm](const type &c) -> const D &{ return c.*pm; }, is_method(*this));
|
||||||
def_property_readonly(name, fget, return_value_policy::reference_internal, extra...);
|
def_property_readonly(name, fget, return_value_policy::reference_internal, extra...);
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -59,6 +59,7 @@ set(PYBIND11_TEST_FILES
|
|||||||
test_stl.cpp
|
test_stl.cpp
|
||||||
test_stl_binders.cpp
|
test_stl_binders.cpp
|
||||||
test_tagbased_polymorphic.cpp
|
test_tagbased_polymorphic.cpp
|
||||||
|
test_union.cpp
|
||||||
test_virtual_functions.cpp
|
test_virtual_functions.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
22
tests/test_union.cpp
Normal file
22
tests/test_union.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
tests/test_class.cpp -- test py::class_ definitions and basic functionality
|
||||||
|
|
||||||
|
Copyright (c) 2019 Roland Dreier <roland.dreier@gmail.com>
|
||||||
|
|
||||||
|
All rights reserved. Use of this source code is governed by a
|
||||||
|
BSD-style license that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
|
TEST_SUBMODULE(union_, m) {
|
||||||
|
union TestUnion {
|
||||||
|
int value_int;
|
||||||
|
unsigned value_uint;
|
||||||
|
};
|
||||||
|
|
||||||
|
py::class_<TestUnion>(m, "TestUnion")
|
||||||
|
.def(py::init<>())
|
||||||
|
.def_readonly("as_int", &TestUnion::value_int)
|
||||||
|
.def_readwrite("as_uint", &TestUnion::value_uint);
|
||||||
|
}
|
8
tests/test_union.py
Normal file
8
tests/test_union.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from pybind11_tests import union_ as m
|
||||||
|
|
||||||
|
|
||||||
|
def test_union():
|
||||||
|
instance = m.TestUnion()
|
||||||
|
|
||||||
|
instance.as_uint = 10
|
||||||
|
assert instance.as_int == 10
|
Loading…
Reference in New Issue
Block a user