15 #ifndef PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL
16 # define PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL
23 #if defined(PYBIND11_TEST_BOOST)
24 # include <boost/optional.hpp>
38 #if defined(PYBIND11_HAS_VARIANT)
40 # define PYBIND11_TEST_VARIANT 1
41 #elif defined(PYBIND11_TEST_BOOST)
42 # include <boost/variant.hpp>
43 # define PYBIND11_TEST_VARIANT 1
48 template <
typename... Ts>
53 template <
typename... Args>
54 static auto call(Args &&...
args) -> decltype(boost::apply_visitor(
args...)) {
55 return boost::apply_visitor(
args...);
78 template <
template <
typename>
class OptionalImpl,
typename T>
95 template <
template <
typename>
class OptionalImpl>
121 template <
typename T>
140 template <
typename... Args>
156 explicit operator bool() const noexcept {
return !
storage.empty(); }
164 template <
typename T>
172 m.def(
"cast_vector", []() {
return std::vector<int>{1}; });
173 m.def(
"load_vector", [](
const std::vector<int> &
v) {
return v.at(0) == 1 &&
v.at(1) == 2; });
175 m.def(
"cast_bool_vector", []() {
return std::vector<bool>{
true,
false}; });
176 m.def(
"load_bool_vector",
177 [](
const std::vector<bool> &
v) {
return v.at(0) ==
true &&
v.at(1) ==
false; });
183 static auto *
v =
new std::vector<RValueCaster>{2};
186 py::return_value_policy::reference);
189 m.def(
"cast_deque", []() {
return std::deque<int>{1}; });
190 m.def(
"load_deque", [](
const std::deque<int> &
v) {
return v.at(0) == 1 &&
v.at(1) == 2; });
193 m.def(
"cast_array", []() {
return std::array<int, 2>{{1, 2}}; });
194 m.def(
"load_array", [](
const std::array<int, 2> &
a) {
return a[0] == 1 &&
a[1] == 2; });
197 m.def(
"cast_valarray", []() {
return std::valarray<int>{1, 4, 9}; });
198 m.def(
"load_valarray", [](
const std::valarray<int> &
v) {
199 return v.size() == 3 &&
v[0] == 1 &&
v[1] == 4 &&
v[2] == 9;
203 m.def(
"cast_map", []() {
return std::map<std::string, std::string>{{
"key",
"value"}}; });
204 m.def(
"load_map", [](
const std::map<std::string, std::string> &map) {
205 return map.at(
"key") ==
"value" && map.at(
"key2") ==
"value2";
209 m.def(
"cast_set", []() {
return std::set<std::string>{
"key1",
"key2"}; });
210 m.def(
"load_set", [](
const std::set<std::string> &
set) {
211 return (
set.count(
"key1") != 0u) && (
set.count(
"key2") != 0u) && (
set.count(
"key3") != 0u);
215 m.def(
"cast_rv_vector", []() {
return std::vector<RValueCaster>{2}; });
216 m.def(
"cast_rv_array", []() {
return std::array<RValueCaster, 3>(); });
221 []() {
return std::unordered_map<std::string, RValueCaster>{{
"a",
RValueCaster{}}}; });
222 m.def(
"cast_rv_nested", []() {
223 std::vector<std::array<std::list<std::unordered_map<std::string, RValueCaster>>, 2>>
v;
225 v.back()[0].emplace_back();
228 v.back()[1].emplace_back();
232 static std::array<RValueCaster, 2> lva;
233 static std::unordered_map<std::string, RValueCaster> lvm{{
"a",
RValueCaster{}},
235 static std::unordered_map<std::string, std::vector<std::list<std::array<RValueCaster, 2>>>>
237 lvn[
"a"].emplace_back();
238 lvn[
"a"].back().emplace_back();
239 lvn[
"a"].emplace_back();
240 lvn[
"a"].back().emplace_back();
241 lvn[
"b"].emplace_back();
242 lvn[
"b"].back().emplace_back();
243 lvn[
"b"].back().emplace_back();
244 static std::vector<RValueCaster> lvv{2};
245 m.def(
"cast_lv_vector", []() ->
const decltype(lvv) & {
return lvv; });
246 m.def(
"cast_lv_array", []() ->
const decltype(lva) & {
return lva; });
247 m.def(
"cast_lv_map", []() ->
const decltype(lvm) & {
return lvm; });
248 m.def(
"cast_lv_nested", []() ->
const decltype(lvn) & {
return lvn; });
250 m.def(
"cast_unique_ptr_vector", []() {
251 std::vector<std::unique_ptr<UserType>>
v;
252 v.emplace_back(
new UserType{7});
253 v.emplace_back(
new UserType{42});
257 pybind11::enum_<EnumType>(
m,
"EnumType")
262 struct MoveOutContainer {
266 std::list<Value> move_list()
const {
return {{0}, {1}, {2}}; }
268 py::class_<MoveOutContainer::Value>(
m,
"MoveOutContainerValue")
270 py::class_<MoveOutContainer>(
m,
"MoveOutContainer")
272 .def_property_readonly(
"move_list", &MoveOutContainer::move_list);
279 NoAssign(
const NoAssign &) =
default;
280 NoAssign(NoAssign &&) =
default;
282 NoAssign &operator=(
const NoAssign &) =
delete;
283 NoAssign &operator=(NoAssign &&) =
delete;
285 py::class_<NoAssign>(
m,
"NoAssign",
"Class with no C++ assignment operators")
287 .def(py::init<int>());
289 struct MoveOutDetector {
290 MoveOutDetector() =
default;
291 MoveOutDetector(
const MoveOutDetector &) =
default;
292 MoveOutDetector(MoveOutDetector &&
other) noexcept : initialized(
other.initialized) {
294 other.initialized =
false;
296 bool initialized =
true;
298 py::class_<MoveOutDetector>(
m,
"MoveOutDetector",
"Class with move tracking")
300 .def_readonly(
"initialized", &MoveOutDetector::initialized);
302 #ifdef PYBIND11_HAS_OPTIONAL
304 m.attr(
"has_optional") =
true;
306 using opt_int = std::optional<int>;
307 using opt_no_assign = std::optional<NoAssign>;
308 m.def(
"double_or_zero", [](
const opt_int &
x) ->
int {
return x.value_or(0) * 2; });
309 m.def(
"half_or_none", [](
int x) -> opt_int {
return x != 0 ? opt_int(
x / 2) : opt_int(); });
312 [](opt_int
x) {
return x.value_or(42); },
313 py::arg_v(
"x", std::nullopt,
"None"));
316 [](
const opt_no_assign &
x) {
return x ?
x->value : 42; },
317 py::arg_v(
"x", std::nullopt,
"None"));
319 m.def(
"nodefer_none_optional", [](std::optional<int>) {
return true; });
320 m.def(
"nodefer_none_optional", [](
const py::none &) {
return false; });
323 py::class_<opt_holder>(
m,
"OptionalHolder",
"Class with optional member")
325 .def_readonly(
"member", &opt_holder::member)
326 .def(
"member_initialized", &opt_holder::member_initialized);
329 pybind11::class_<opt_props>(
m,
"OptionalProperties")
330 .def(pybind11::init<>())
331 .def_property_readonly(
"access_by_ref", &opt_props::access_by_ref)
332 .def_property_readonly(
"access_by_copy", &opt_props::access_by_copy);
335 #ifdef PYBIND11_HAS_EXP_OPTIONAL
337 m.attr(
"has_exp_optional") =
true;
339 using exp_opt_int = std::experimental::optional<int>;
340 using exp_opt_no_assign = std::experimental::optional<NoAssign>;
341 m.def(
"double_or_zero_exp", [](
const exp_opt_int &
x) ->
int {
return x.value_or(0) * 2; });
342 m.def(
"half_or_none_exp",
343 [](
int x) -> exp_opt_int {
return x ? exp_opt_int(
x / 2) : exp_opt_int(); });
346 [](exp_opt_int
x) {
return x.value_or(42); },
347 py::arg_v(
"x", std::experimental::nullopt,
"None"));
349 "test_no_assign_exp",
350 [](
const exp_opt_no_assign &
x) {
return x ?
x->value : 42; },
351 py::arg_v(
"x", std::experimental::nullopt,
"None"));
354 py::class_<opt_exp_holder>(
m,
"OptionalExpHolder",
"Class with optional member")
356 .def_readonly(
"member", &opt_exp_holder::member)
357 .def(
"member_initialized", &opt_exp_holder::member_initialized);
360 pybind11::class_<opt_exp_props>(
m,
"OptionalExpProperties")
361 .def(pybind11::init<>())
362 .def_property_readonly(
"access_by_ref", &opt_exp_props::access_by_ref)
363 .def_property_readonly(
"access_by_copy", &opt_exp_props::access_by_copy);
366 #if defined(PYBIND11_TEST_BOOST)
368 m.attr(
"has_boost_optional") =
true;
370 using boost_opt_int = boost::optional<int>;
371 using boost_opt_no_assign = boost::optional<NoAssign>;
372 m.def(
"double_or_zero_boost", [](
const boost_opt_int &
x) ->
int {
return x.value_or(0) * 2; });
373 m.def(
"half_or_none_boost",
374 [](
int x) -> boost_opt_int {
return x != 0 ? boost_opt_int(
x / 2) : boost_opt_int(); });
376 "test_nullopt_boost",
377 [](boost_opt_int
x) {
return x.value_or(42); },
378 py::arg_v(
"x", boost::none,
"None"));
380 "test_no_assign_boost",
381 [](
const boost_opt_no_assign &
x) {
return x ?
x->value : 42; },
382 py::arg_v(
"x", boost::none,
"None"));
385 py::class_<opt_boost_holder>(
m,
"OptionalBoostHolder",
"Class with optional member")
387 .def_readonly(
"member", &opt_boost_holder::member)
388 .def(
"member_initialized", &opt_boost_holder::member_initialized);
391 pybind11::class_<opt_boost_props>(
m,
"OptionalBoostProperties")
392 .def(pybind11::init<>())
393 .def_property_readonly(
"access_by_ref", &opt_boost_props::access_by_ref)
394 .def_property_readonly(
"access_by_copy", &opt_boost_props::access_by_copy);
400 m.def(
"double_or_zero_refsensitive",
401 [](
const refsensitive_opt_int &
x) ->
int {
return (
x ?
x.value() : 0) * 2; });
402 m.def(
"half_or_none_refsensitive", [](
int x) -> refsensitive_opt_int {
403 return x != 0 ? refsensitive_opt_int(
x / 2) : refsensitive_opt_int();
406 "test_nullopt_refsensitive",
408 [](refsensitive_opt_int
x) {
return x ?
x.value() : 42; },
409 py::arg_v(
"x", refsensitive_opt_int(),
"None"));
411 "test_no_assign_refsensitive",
412 [](
const refsensitive_opt_no_assign &
x) {
return x ?
x->value : 42; },
413 py::arg_v(
"x", refsensitive_opt_no_assign(),
"None"));
416 py::class_<opt_refsensitive_holder>(
417 m,
"OptionalRefSensitiveHolder",
"Class with optional member")
419 .def_readonly(
"member", &opt_refsensitive_holder::member)
420 .def(
"member_initialized", &opt_refsensitive_holder::member_initialized);
423 pybind11::class_<opt_refsensitive_props>(
m,
"OptionalRefSensitiveProperties")
424 .def(pybind11::init<>())
425 .def_property_readonly(
"access_by_ref", &opt_refsensitive_props::access_by_ref)
426 .def_property_readonly(
"access_by_copy", &opt_refsensitive_props::access_by_copy);
428 #ifdef PYBIND11_HAS_FILESYSTEM
430 m.attr(
"has_filesystem") =
true;
434 #ifdef PYBIND11_TEST_VARIANT
436 "visitor::result_type is required by boost::variant in C++11 mode");
439 using result_type =
const char *;
442 result_type
operator()(
const std::string &) {
return "std::string"; }
443 result_type
operator()(
double) {
return "double"; }
444 result_type
operator()(std::nullptr_t) {
return "std::nullptr_t"; }
445 # if defined(PYBIND11_HAS_VARIANT)
446 result_type
operator()(std::monostate) {
return "std::monostate"; }
451 m.def(
"load_variant", [](
const variant<int, std::string, double, std::nullptr_t> &
v) {
452 return py::detail::visit_helper<variant>::call(visitor(),
v);
454 m.def(
"load_variant_2pass", [](variant<double, int>
v) {
455 return py::detail::visit_helper<variant>::call(visitor(),
v);
457 m.def(
"cast_variant", []() {
458 using V = variant<int, std::string>;
462 # if defined(PYBIND11_HAS_VARIANT)
464 m.def(
"load_monostate_variant",
465 [](
const variant<std::monostate, int, std::string> &
v) ->
const char * {
466 return py::detail::visit_helper<variant>::call(visitor(),
v);
468 m.def(
"cast_monostate_variant", []() {
469 using V = variant<std::monostate, int, std::string>;
477 m.def(
"tpl_ctor_vector", [](std::vector<TplCtorClass> &) {});
478 m.def(
"tpl_ctor_map", [](std::unordered_map<TplCtorClass, TplCtorClass> &) {});
479 m.def(
"tpl_ctor_set", [](std::unordered_set<TplCtorClass> &) {});
480 #if defined(PYBIND11_HAS_OPTIONAL)
481 m.def(
"tpl_constr_optional", [](std::optional<TplCtorClass> &) {});
483 #if defined(PYBIND11_HAS_EXP_OPTIONAL)
484 m.def(
"tpl_constr_optional_exp", [](std::experimental::optional<TplCtorClass> &) {});
486 #if defined(PYBIND11_TEST_BOOST)
487 m.def(
"tpl_constr_optional_boost", [](boost::optional<TplCtorClass> &) {});
492 m.def(
"return_vec_of_reference_wrapper", [](std::reference_wrapper<UserType>
p4) {
493 static UserType
p1{1},
p2{2},
p3{3};
494 return std::vector<std::reference_wrapper<UserType>>{
499 m.def(
"stl_pass_by_pointer", [](std::vector<int> *
v) {
return *
v; },
"v"_a =
nullptr);
502 m.def(
"func_with_string_or_vector_string_arg_overload",
503 [](
const std::vector<std::string> &) {
return 1; });
504 m.def(
"func_with_string_or_vector_string_arg_overload",
505 [](
const std::list<std::string> &) {
return 2; });
506 m.def(
"func_with_string_or_vector_string_arg_overload", [](
const std::string &) {
return 3; });
511 Placeholder(
const Placeholder &) =
delete;
514 py::class_<Placeholder>(
m,
"Placeholder");
518 "test_stl_ownership",
520 std::vector<Placeholder *>
result;
521 result.push_back(
new Placeholder());
524 py::return_value_policy::take_ownership);
526 m.def(
"array_cast_sequence", [](std::array<int, 3>
x) {
return x; });
529 struct Issue1561Inner {
532 struct Issue1561Outer {
533 std::vector<Issue1561Inner> list;
536 py::class_<Issue1561Inner>(
m,
"Issue1561Inner")
537 .def(py::init<std::string>())
540 py::class_<Issue1561Outer>(
m,
"Issue1561Outer")
542 .def_readwrite(
"list", &Issue1561Outer::list);
545 "return_vector_bool_raw_ptr",
546 []() {
return new std::vector<bool>(4513); },
548 py::return_value_policy::take_ownership);