18 #if defined(PYBIND11_HAS_VARIANT)
20 #elif defined(PYBIND11_TEST_BOOST) && (!defined(_MSC_VER) || _MSC_VER >= 1910)
21 # include <boost/variant.hpp>
22 # define PYBIND11_HAS_VARIANT 1
25 namespace pybind11 {
namespace detail {
26 template <
typename... Ts>
31 template <
typename... Args>
32 static auto call(Args &&...
args) -> decltype(boost::apply_visitor(
args...)) {
33 return boost::apply_visitor(
args...);
53 template <
template <
typename>
class OptionalImpl,
typename T>
66 m.def(
"cast_vector", []() {
return std::vector<int>{1}; });
67 m.def(
"load_vector", [](
const std::vector<int> &v) {
return v.at(0) == 1 && v.at(1) == 2; });
69 m.def(
"cast_bool_vector", []() {
return std::vector<bool>{
true,
false}; });
70 m.def(
"load_bool_vector", [](
const std::vector<bool> &v) {
71 return v.at(0) ==
true && v.at(1) ==
false;
74 static std::vector<RValueCaster> lvv{2};
75 m.def(
"cast_ptr_vector", []() {
return &lvv; });
78 m.def(
"cast_deque", []() {
return std::deque<int>{1}; });
79 m.def(
"load_deque", [](
const std::deque<int> &v) {
return v.at(0) == 1 && v.at(1) == 2; });
82 m.def(
"cast_array", []() {
return std::array<int, 2> {{1 , 2}}; });
83 m.def(
"load_array", [](
const std::array<int, 2> &a) {
return a[0] == 1 && a[1] == 2; });
86 m.def(
"cast_valarray", []() {
return std::valarray<int>{1, 4, 9}; });
87 m.def(
"load_valarray", [](
const std::valarray<int>& v) {
88 return v.size() == 3 && v[0] == 1 && v[1] == 4 && v[2] == 9;
92 m.def(
"cast_map", []() {
return std::map<std::string, std::string>{{
"key",
"value"}}; });
93 m.def(
"load_map", [](
const std::map<std::string, std::string> &map) {
94 return map.at(
"key") ==
"value" && map.at(
"key2") ==
"value2";
98 m.def(
"cast_set", []() {
return std::set<std::string>{
"key1",
"key2"}; });
99 m.def(
"load_set", [](
const std::set<std::string> &
set) {
100 return set.count(
"key1") &&
set.count(
"key2") &&
set.count(
"key3");
104 m.def(
"cast_rv_vector", []() {
return std::vector<RValueCaster>{2}; });
105 m.def(
"cast_rv_array", []() {
return std::array<RValueCaster, 3>(); });
109 m.def(
"cast_rv_map", []() {
return std::unordered_map<std::string, RValueCaster>{{
"a",
RValueCaster{}}}; });
110 m.def(
"cast_rv_nested", []() {
111 std::vector<std::array<std::list<std::unordered_map<std::string, RValueCaster>>, 2>> v;
113 v.back()[0].emplace_back();
116 v.back()[1].emplace_back();
120 static std::array<RValueCaster, 2> lva;
122 static std::unordered_map<std::string, std::vector<std::list<std::array<RValueCaster, 2>>>> lvn;
123 lvn[
"a"].emplace_back();
124 lvn[
"a"].back().emplace_back();
125 lvn[
"a"].emplace_back();
126 lvn[
"a"].back().emplace_back();
127 lvn[
"b"].emplace_back();
128 lvn[
"b"].back().emplace_back();
129 lvn[
"b"].back().emplace_back();
130 m.def(
"cast_lv_vector", []() ->
const decltype(lvv) & {
return lvv; });
131 m.def(
"cast_lv_array", []() ->
const decltype(lva) & {
return lva; });
132 m.def(
"cast_lv_map", []() ->
const decltype(lvm) & {
return lvm; });
133 m.def(
"cast_lv_nested", []() ->
const decltype(lvn) & {
return lvn; });
135 m.def(
"cast_unique_ptr_vector", []() {
136 std::vector<std::unique_ptr<UserType>> v;
137 v.emplace_back(
new UserType{7});
138 v.emplace_back(
new UserType{42});
143 struct MoveOutContainer {
144 struct Value {
int value; };
145 std::list<Value> move_list()
const {
return {{0}, {1}, {2}}; }
147 py::class_<MoveOutContainer::Value>(
m,
"MoveOutContainerValue")
149 py::class_<MoveOutContainer>(
m,
"MoveOutContainer")
151 .def_property_readonly(
"move_list", &MoveOutContainer::move_list);
158 NoAssign(
const NoAssign &) =
default;
159 NoAssign(NoAssign &&) =
default;
161 NoAssign &operator=(
const NoAssign &) =
delete;
162 NoAssign &operator=(NoAssign &&) =
delete;
164 py::class_<NoAssign>(
m,
"NoAssign",
"Class with no C++ assignment operators")
166 .def(py::init<int>());
169 struct MoveOutDetector
171 MoveOutDetector() =
default;
172 MoveOutDetector(
const MoveOutDetector&) =
default;
173 MoveOutDetector(MoveOutDetector&& other) noexcept
174 : initialized(other.initialized) {
176 other.initialized =
false;
178 bool initialized =
true;
180 py::class_<MoveOutDetector>(
m,
"MoveOutDetector",
"Class with move tracking")
182 .def_readonly(
"initialized", &MoveOutDetector::initialized);
185 #ifdef PYBIND11_HAS_OPTIONAL
187 m.attr(
"has_optional") =
true;
189 using opt_int = std::optional<int>;
190 using opt_no_assign = std::optional<NoAssign>;
191 m.def(
"double_or_zero", [](
const opt_int&
x) ->
int {
192 return x.value_or(0) * 2;
194 m.def(
"half_or_none", [](
int x) -> opt_int {
195 return x ? opt_int(
x / 2) : opt_int();
197 m.def(
"test_nullopt", [](opt_int
x) {
198 return x.value_or(42);
199 }, py::arg_v(
"x", std::nullopt,
"None"));
200 m.def(
"test_no_assign", [](
const opt_no_assign &
x) {
201 return x ?
x->value : 42;
202 }, py::arg_v(
"x", std::nullopt,
"None"));
204 m.def(
"nodefer_none_optional", [](std::optional<int>) {
return true; });
205 m.def(
"nodefer_none_optional", [](py::none) {
return false; });
208 py::class_<opt_holder>(
m,
"OptionalHolder",
"Class with optional member")
210 .def_readonly(
"member", &opt_holder::member)
211 .def(
"member_initialized", &opt_holder::member_initialized);
214 #ifdef PYBIND11_HAS_EXP_OPTIONAL
216 m.attr(
"has_exp_optional") =
true;
218 using exp_opt_int = std::experimental::optional<int>;
219 using exp_opt_no_assign = std::experimental::optional<NoAssign>;
220 m.def(
"double_or_zero_exp", [](
const exp_opt_int&
x) ->
int {
221 return x.value_or(0) * 2;
223 m.def(
"half_or_none_exp", [](
int x) -> exp_opt_int {
224 return x ? exp_opt_int(
x / 2) : exp_opt_int();
226 m.def(
"test_nullopt_exp", [](exp_opt_int
x) {
227 return x.value_or(42);
228 }, py::arg_v(
"x", std::experimental::nullopt,
"None"));
229 m.def(
"test_no_assign_exp", [](
const exp_opt_no_assign &
x) {
230 return x ?
x->value : 42;
231 }, py::arg_v(
"x", std::experimental::nullopt,
"None"));
234 py::class_<opt_exp_holder>(
m,
"OptionalExpHolder",
"Class with optional member")
236 .def_readonly(
"member", &opt_exp_holder::member)
237 .def(
"member_initialized", &opt_exp_holder::member_initialized);
240 #ifdef PYBIND11_HAS_VARIANT
242 "visitor::result_type is required by boost::variant in C++11 mode");
245 using result_type =
const char *;
247 result_type operator()(
int) {
return "int"; }
248 result_type operator()(std::string) {
return "std::string"; }
249 result_type operator()(
double) {
return "double"; }
250 result_type operator()(std::nullptr_t) {
return "std::nullptr_t"; }
254 m.def(
"load_variant", [](variant<int, std::string, double, std::nullptr_t> v) {
255 return py::detail::visit_helper<variant>::call(visitor(), v);
257 m.def(
"load_variant_2pass", [](variant<double, int> v) {
258 return py::detail::visit_helper<variant>::call(visitor(), v);
260 m.def(
"cast_variant", []() {
261 using V = variant<int, std::string>;
268 m.def(
"tpl_ctor_vector", [](std::vector<TplCtorClass> &) {});
269 m.def(
"tpl_ctor_map", [](std::unordered_map<TplCtorClass, TplCtorClass> &) {});
270 m.def(
"tpl_ctor_set", [](std::unordered_set<TplCtorClass> &) {});
271 #if defined(PYBIND11_HAS_OPTIONAL)
272 m.def(
"tpl_constr_optional", [](std::optional<TplCtorClass> &) {});
273 #elif defined(PYBIND11_HAS_EXP_OPTIONAL)
274 m.def(
"tpl_constr_optional", [](std::experimental::optional<TplCtorClass> &) {});
279 m.def(
"return_vec_of_reference_wrapper", [](std::reference_wrapper<UserType> p4) {
280 static UserType p1{1}, p2{2}, p3{3};
281 return std::vector<std::reference_wrapper<UserType>> {
287 m.def(
"stl_pass_by_pointer", [](std::vector<int>* v) {
return *v; },
"v"_a=
nullptr);
290 m.def(
"func_with_string_or_vector_string_arg_overload", [](std::vector<std::string>) {
return 1; });
291 m.def(
"func_with_string_or_vector_string_arg_overload", [](std::list<std::string>) {
return 2; });
292 m.def(
"func_with_string_or_vector_string_arg_overload", [](std::string) {
return 3; });
297 Placeholder(
const Placeholder &) =
delete;
300 py::class_<Placeholder>(
m,
"Placeholder");
303 m.def(
"test_stl_ownership",
305 std::vector<Placeholder *> result;
306 result.push_back(
new Placeholder());
309 py::return_value_policy::take_ownership);
311 m.def(
"array_cast_sequence", [](std::array<int, 3>
x) {
return x; });
314 struct Issue1561Inner { std::string
data; };
315 struct Issue1561Outer { std::vector<Issue1561Inner>
list; };
317 py::class_<Issue1561Inner>(
m,
"Issue1561Inner")
318 .def(py::init<std::string>())
321 py::class_<Issue1561Outer>(
m,
"Issue1561Outer")
323 .def_readwrite(
"list", &Issue1561Outer::list);