10#include <pybind11/stl.h>
15#ifndef PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL
16# define PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL
18#include <pybind11/stl/filesystem.h>
23#if defined(PYBIND11_TEST_BOOST)
24# include <boost/optional.hpp>
38#if defined(PYBIND11_HAS_VARIANT)
40#elif defined(PYBIND11_TEST_BOOST) && (!defined(_MSC_VER) || _MSC_VER >= 1910)
41# include <boost/variant.hpp>
42# define PYBIND11_HAS_VARIANT 1
47template <
typename... Ts>
52 template <
typename... Args>
53 static auto call(Args &&...
args) ->
decltype(boost::apply_visitor(
args...)) {
54 return boost::apply_visitor(
args...);
77template <
template <
typename>
class OptionalImpl,
typename T>
94template <
template <
typename>
class OptionalImpl>
104 value = EnumType::kUnset;
139 template <
typename... Args>
155 explicit operator bool() const noexcept {
return !
storage.empty(); }
171 m.def(
"cast_vector", []() {
return std::vector<int>{1}; });
172 m.def(
"load_vector", [](
const std::vector<int> &v) {
return v.at(0) == 1 && v.at(1) == 2; });
174 m.def(
"cast_bool_vector", []() {
return std::vector<bool>{
true,
false}; });
175 m.def(
"load_bool_vector",
176 [](
const std::vector<bool> &v) {
return v.at(0) ==
true && v.at(1) ==
false; });
178 static std::vector<RValueCaster> lvv{2};
179 m.def(
"cast_ptr_vector", []() {
return &lvv; });
182 m.def(
"cast_deque", []() {
return std::deque<int>{1}; });
183 m.def(
"load_deque", [](
const std::deque<int> &v) {
return v.at(0) == 1 && v.at(1) == 2; });
186 m.def(
"cast_array", []() {
return std::array<int, 2>{{1, 2}}; });
187 m.def(
"load_array", [](
const std::array<int, 2> &a) {
return a[0] == 1 && a[1] == 2; });
190 m.def(
"cast_valarray", []() {
return std::valarray<int>{1, 4, 9}; });
191 m.def(
"load_valarray", [](
const std::valarray<int> &v) {
192 return v.size() == 3 && v[0] == 1 && v[1] == 4 && v[2] == 9;
196 m.def(
"cast_map", []() {
return std::map<std::string, std::string>{{
"key",
"value"}}; });
197 m.def(
"load_map", [](
const std::map<std::string, std::string> &map) {
198 return map.at(
"key") ==
"value" && map.at(
"key2") ==
"value2";
202 m.def(
"cast_set", []() {
return std::set<std::string>{
"key1",
"key2"}; });
203 m.def(
"load_set", [](
const std::set<std::string> &
set) {
204 return (
set.count(
"key1") != 0u) && (
set.count(
"key2") != 0u) && (
set.count(
"key3") != 0u);
208 m.def(
"cast_rv_vector", []() {
return std::vector<RValueCaster>{2}; });
209 m.def(
"cast_rv_array", []() {
return std::array<RValueCaster, 3>(); });
213 m.def(
"cast_rv_map", []() {
214 return std::unordered_map<std::string, RValueCaster>{{
"a",
RValueCaster{}}};
216 m.def(
"cast_rv_nested", []() {
217 std::vector<std::array<std::list<std::unordered_map<std::string, RValueCaster>>, 2>> v;
219 v.back()[0].emplace_back();
222 v.back()[1].emplace_back();
226 static std::array<RValueCaster, 2> lva;
227 static std::unordered_map<std::string, RValueCaster> lvm{{
"a",
RValueCaster{}},
229 static std::unordered_map<std::string, std::vector<std::list<std::array<RValueCaster, 2>>>>
231 lvn[
"a"].emplace_back();
232 lvn[
"a"].back().emplace_back();
233 lvn[
"a"].emplace_back();
234 lvn[
"a"].back().emplace_back();
235 lvn[
"b"].emplace_back();
236 lvn[
"b"].back().emplace_back();
237 lvn[
"b"].back().emplace_back();
238 m.def(
"cast_lv_vector", []() ->
const decltype(lvv) & {
return lvv; });
239 m.def(
"cast_lv_array", []() ->
const decltype(lva) & {
return lva; });
240 m.def(
"cast_lv_map", []() ->
const decltype(lvm) & {
return lvm; });
241 m.def(
"cast_lv_nested", []() ->
const decltype(lvn) & {
return lvn; });
243 m.def(
"cast_unique_ptr_vector", []() {
244 std::vector<std::unique_ptr<UserType>> v;
250 pybind11::enum_<EnumType>(m,
"EnumType")
255 struct MoveOutContainer {
259 std::list<Value> move_list()
const {
return {{0}, {1}, {2}}; }
261 py::class_<MoveOutContainer::Value>(m,
"MoveOutContainerValue")
262 .def_readonly(
"value", &MoveOutContainer::Value::value);
263 py::class_<MoveOutContainer>(m,
"MoveOutContainer")
265 .def_property_readonly(
"move_list", &MoveOutContainer::move_list);
271 explicit NoAssign(
int value = 0) : value(value) {}
272 NoAssign(
const NoAssign &) =
default;
273 NoAssign(NoAssign &&) =
default;
275 NoAssign &operator=(
const NoAssign &) =
delete;
276 NoAssign &operator=(NoAssign &&) =
delete;
278 py::class_<NoAssign>(m,
"NoAssign",
"Class with no C++ assignment operators")
280 .def(py::init<int>());
282 struct MoveOutDetector {
283 MoveOutDetector() =
default;
284 MoveOutDetector(
const MoveOutDetector &) =
default;
285 MoveOutDetector(MoveOutDetector &&other) noexcept : initialized(other.initialized) {
287 other.initialized =
false;
289 bool initialized =
true;
291 py::class_<MoveOutDetector>(m,
"MoveOutDetector",
"Class with move tracking")
293 .def_readonly(
"initialized", &MoveOutDetector::initialized);
295#ifdef PYBIND11_HAS_OPTIONAL
297 m.attr(
"has_optional") =
true;
299 using opt_int = std::optional<int>;
300 using opt_no_assign = std::optional<NoAssign>;
301 m.def(
"double_or_zero", [](
const opt_int &x) ->
int {
return x.value_or(0) * 2; });
302 m.def(
"half_or_none", [](
int x) -> opt_int {
return x != 0 ? opt_int(x / 2) : opt_int(); });
305 [](opt_int x) {
return x.value_or(42); },
306 py::arg_v(
"x", std::nullopt,
"None"));
309 [](
const opt_no_assign &x) {
return x ? x->value : 42; },
310 py::arg_v(
"x", std::nullopt,
"None"));
312 m.def(
"nodefer_none_optional", [](std::optional<int>) {
return true; });
313 m.def(
"nodefer_none_optional", [](
const py::none &) {
return false; });
316 py::class_<opt_holder>(m,
"OptionalHolder",
"Class with optional member")
318 .def_readonly(
"member", &opt_holder::member)
319 .def(
"member_initialized", &opt_holder::member_initialized);
322 pybind11::class_<opt_props>(m,
"OptionalProperties")
323 .def(pybind11::init<>())
324 .def_property_readonly(
"access_by_ref", &opt_props::access_by_ref)
325 .def_property_readonly(
"access_by_copy", &opt_props::access_by_copy);
328#ifdef PYBIND11_HAS_EXP_OPTIONAL
330 m.attr(
"has_exp_optional") =
true;
332 using exp_opt_int = std::experimental::optional<int>;
333 using exp_opt_no_assign = std::experimental::optional<NoAssign>;
334 m.def(
"double_or_zero_exp", [](
const exp_opt_int &x) ->
int {
return x.value_or(0) * 2; });
335 m.def(
"half_or_none_exp",
336 [](
int x) -> exp_opt_int {
return x ? exp_opt_int(x / 2) : exp_opt_int(); });
339 [](exp_opt_int x) {
return x.value_or(42); },
340 py::arg_v(
"x", std::experimental::nullopt,
"None"));
342 "test_no_assign_exp",
343 [](
const exp_opt_no_assign &x) {
return x ? x->value : 42; },
344 py::arg_v(
"x", std::experimental::nullopt,
"None"));
347 py::class_<opt_exp_holder>(m,
"OptionalExpHolder",
"Class with optional member")
349 .def_readonly(
"member", &opt_exp_holder::member)
350 .def(
"member_initialized", &opt_exp_holder::member_initialized);
353 pybind11::class_<opt_exp_props>(m,
"OptionalExpProperties")
354 .def(pybind11::init<>())
355 .def_property_readonly(
"access_by_ref", &opt_exp_props::access_by_ref)
356 .def_property_readonly(
"access_by_copy", &opt_exp_props::access_by_copy);
359#if defined(PYBIND11_TEST_BOOST)
361 m.attr(
"has_boost_optional") =
true;
363 using boost_opt_int = boost::optional<int>;
364 using boost_opt_no_assign = boost::optional<NoAssign>;
365 m.def(
"double_or_zero_boost", [](
const boost_opt_int &x) ->
int {
return x.value_or(0) * 2; });
366 m.def(
"half_or_none_boost",
367 [](
int x) -> boost_opt_int {
return x != 0 ? boost_opt_int(x / 2) : boost_opt_int(); });
369 "test_nullopt_boost",
370 [](boost_opt_int x) {
return x.value_or(42); },
371 py::arg_v(
"x", boost::none,
"None"));
373 "test_no_assign_boost",
374 [](
const boost_opt_no_assign &x) {
return x ? x->value : 42; },
375 py::arg_v(
"x", boost::none,
"None"));
378 py::class_<opt_boost_holder>(m,
"OptionalBoostHolder",
"Class with optional member")
380 .def_readonly(
"member", &opt_boost_holder::member)
381 .def(
"member_initialized", &opt_boost_holder::member_initialized);
384 pybind11::class_<opt_boost_props>(m,
"OptionalBoostProperties")
385 .def(pybind11::init<>())
386 .def_property_readonly(
"access_by_ref", &opt_boost_props::access_by_ref)
387 .def_property_readonly(
"access_by_copy", &opt_boost_props::access_by_copy);
393 m.def(
"double_or_zero_refsensitive",
394 [](
const refsensitive_opt_int &x) ->
int {
return (x ? x.value() : 0) * 2; });
395 m.def(
"half_or_none_refsensitive", [](
int x) -> refsensitive_opt_int {
396 return x != 0 ? refsensitive_opt_int(x / 2) : refsensitive_opt_int();
399 "test_nullopt_refsensitive",
401 [](refsensitive_opt_int x) {
return x ? x.value() : 42; },
402 py::arg_v(
"x", refsensitive_opt_int(),
"None"));
404 "test_no_assign_refsensitive",
405 [](
const refsensitive_opt_no_assign &x) {
return x ? x->value : 42; },
406 py::arg_v(
"x", refsensitive_opt_no_assign(),
"None"));
409 py::class_<opt_refsensitive_holder>(
410 m,
"OptionalRefSensitiveHolder",
"Class with optional member")
412 .def_readonly(
"member", &opt_refsensitive_holder::member)
413 .def(
"member_initialized", &opt_refsensitive_holder::member_initialized);
416 pybind11::class_<opt_refsensitive_props>(m,
"OptionalRefSensitiveProperties")
417 .def(pybind11::init<>())
418 .def_property_readonly(
"access_by_ref", &opt_refsensitive_props::access_by_ref)
419 .def_property_readonly(
"access_by_copy", &opt_refsensitive_props::access_by_copy);
421#ifdef PYBIND11_HAS_FILESYSTEM
423 m.attr(
"has_filesystem") =
true;
424 m.def(
"parent_path", [](
const std::filesystem::path &p) {
return p.parent_path(); });
427#ifdef PYBIND11_HAS_VARIANT
428 static_assert(std::is_same<py::detail::variant_caster_visitor::result_type, py::handle>::value,
429 "visitor::result_type is required by boost::variant in C++11 mode");
432 using result_type =
const char *;
434 result_type operator()(
int) {
return "int"; }
435 result_type operator()(
const std::string &) {
return "std::string"; }
436 result_type operator()(
double) {
return "double"; }
437 result_type operator()(std::nullptr_t) {
return "std::nullptr_t"; }
441 m.def(
"load_variant", [](
const variant<int, std::string, double, std::nullptr_t> &v) {
442 return py::detail::visit_helper<variant>::call(visitor(), v);
444 m.def(
"load_variant_2pass", [](variant<double, int> v) {
445 return py::detail::visit_helper<variant>::call(visitor(), v);
447 m.def(
"cast_variant", []() {
448 using V = variant<int, std::string>;
449 return py::make_tuple(V(5), V(
"Hello"));
455 m.def(
"tpl_ctor_vector", [](std::vector<TplCtorClass> &) {});
456 m.def(
"tpl_ctor_map", [](std::unordered_map<TplCtorClass, TplCtorClass> &) {});
457 m.def(
"tpl_ctor_set", [](std::unordered_set<TplCtorClass> &) {});
458#if defined(PYBIND11_HAS_OPTIONAL)
459 m.def(
"tpl_constr_optional", [](std::optional<TplCtorClass> &) {});
461#if defined(PYBIND11_HAS_EXP_OPTIONAL)
462 m.def(
"tpl_constr_optional_exp", [](std::experimental::optional<TplCtorClass> &) {});
464#if defined(PYBIND11_TEST_BOOST)
465 m.def(
"tpl_constr_optional_boost", [](boost::optional<TplCtorClass> &) {});
470 m.def(
"return_vec_of_reference_wrapper", [](std::reference_wrapper<UserType> p4) {
471 static UserType p1{1}, p2{2}, p3{3};
472 return std::vector<std::reference_wrapper<UserType>>{
473 std::ref(p1), std::ref(p2), std::ref(p3), p4};
478 "stl_pass_by_pointer", [](std::vector<int> *v) {
return *v; },
"v"_a =
nullptr);
481 m.def(
"func_with_string_or_vector_string_arg_overload",
482 [](
const std::vector<std::string> &) {
return 1; });
483 m.def(
"func_with_string_or_vector_string_arg_overload",
484 [](
const std::list<std::string> &) {
return 2; });
485 m.def(
"func_with_string_or_vector_string_arg_overload", [](
const std::string &) {
return 3; });
490 Placeholder(
const Placeholder &) =
delete;
493 py::class_<Placeholder>(m,
"Placeholder");
497 "test_stl_ownership",
499 std::vector<Placeholder *> result;
500 result.push_back(
new Placeholder());
503 py::return_value_policy::take_ownership);
505 m.def(
"array_cast_sequence", [](std::array<int, 3> x) {
return x; });
508 struct Issue1561Inner {
511 struct Issue1561Outer {
512 std::vector<Issue1561Inner>
list;
515 py::class_<Issue1561Inner>(m,
"Issue1561Inner")
516 .def(py::init<std::string>())
517 .def_readwrite(
"data", &Issue1561Inner::data);
519 py::class_<Issue1561Outer>(m,
"Issue1561Outer")
521 .def_readwrite(
"list", &Issue1561Outer::list);
524 "return_vector_bool_raw_ptr",
525 []() {
return new std::vector<bool>(4513); },
527 py::return_value_policy::take_ownership);
OptionalEnumValue & access_by_ref()
OptionalEnumValue access_by_copy()
OptionalImpl< EnumType > OptionalEnumValue
const T & value() const noexcept
const T * operator->() const noexcept
ReferenceSensitiveOptional & operator=(const T &value)
ReferenceSensitiveOptional()=default
ReferenceSensitiveOptional(T &&value)
const T & operator*() const noexcept
ReferenceSensitiveOptional & operator=(T &&value)
ReferenceSensitiveOptional(const T &value)
T & emplace(Args &&...args)
A user-defined type which is exported and can be used by any test.
#define PYBIND11_MAKE_OPAQUE(...)
@ move
Use std::move to move the return value contents into a new instance that will be owned by Python.
void print_created(T *inst, Values &&...values)
void print_destroyed(T *inst, Values &&...values)
#define TEST_SUBMODULE(name, variable)
arr data(const arr &a, Ix... index)
bool member_initialized() const
Custom cast-only type that casts to a string "rvalue" or "lvalue" depending on the cast context.
Issue #528: templated constructor.
bool operator==(const TplCtorClass &) const
size_t operator()(const TplCtorClass &) const
Helper class which abstracts away variant's visit function.