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# define PYBIND11_TEST_VARIANT 1
41#elif defined(PYBIND11_TEST_BOOST)
42# include <boost/variant.hpp>
43# define PYBIND11_TEST_VARIANT 1
48template <
typename... Ts>
53 template <
typename... Args>
54 static auto call(Args &&...
args) ->
decltype(boost::apply_visitor(
args...)) {
55 return boost::apply_visitor(
args...);
78template <
template <
typename>
class OptionalImpl,
typename T>
83 OptionalImpl<T>
member = T{};
95template <
template <
typename>
class OptionalImpl>
105 value = EnumType::kUnset;
140 template <
typename... Args>
156 explicit operator bool() const noexcept {
return !
storage.empty(); }
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>(); });
220 m.def(
"cast_rv_map", []() {
221 return std::unordered_map<std::string, RValueCaster>{{
"a",
RValueCaster{}}};
223 m.def(
"cast_rv_nested", []() {
224 std::vector<std::array<std::list<std::unordered_map<std::string, RValueCaster>>, 2>> v;
226 v.back()[0].emplace_back();
229 v.back()[1].emplace_back();
233 static std::array<RValueCaster, 2> lva;
234 static std::unordered_map<std::string, RValueCaster> lvm{{
"a",
RValueCaster{}},
236 static std::unordered_map<std::string, std::vector<std::list<std::array<RValueCaster, 2>>>>
238 lvn[
"a"].emplace_back();
239 lvn[
"a"].back().emplace_back();
240 lvn[
"a"].emplace_back();
241 lvn[
"a"].back().emplace_back();
242 lvn[
"b"].emplace_back();
243 lvn[
"b"].back().emplace_back();
244 lvn[
"b"].back().emplace_back();
245 static std::vector<RValueCaster> lvv{2};
246 m.def(
"cast_lv_vector", []() ->
const decltype(lvv) & {
return lvv; });
247 m.def(
"cast_lv_array", []() ->
const decltype(lva) & {
return lva; });
248 m.def(
"cast_lv_map", []() ->
const decltype(lvm) & {
return lvm; });
249 m.def(
"cast_lv_nested", []() ->
const decltype(lvn) & {
return lvn; });
251 m.def(
"cast_unique_ptr_vector", []() {
252 std::vector<std::unique_ptr<UserType>> v;
258 pybind11::enum_<EnumType>(m,
"EnumType")
263 struct MoveOutContainer {
267 std::list<Value> move_list()
const {
return {{0}, {1}, {2}}; }
269 py::class_<MoveOutContainer::Value>(m,
"MoveOutContainerValue")
270 .def_readonly(
"value", &MoveOutContainer::Value::value);
271 py::class_<MoveOutContainer>(m,
"MoveOutContainer")
273 .def_property_readonly(
"move_list", &MoveOutContainer::move_list);
279 explicit NoAssign(
int value = 0) : value(value) {}
280 NoAssign(
const NoAssign &) =
default;
281 NoAssign(NoAssign &&) =
default;
283 NoAssign &operator=(
const NoAssign &) =
delete;
284 NoAssign &operator=(NoAssign &&) =
delete;
286 py::class_<NoAssign>(m,
"NoAssign",
"Class with no C++ assignment operators")
288 .def(py::init<int>());
290 struct MoveOutDetector {
291 MoveOutDetector() =
default;
292 MoveOutDetector(
const MoveOutDetector &) =
default;
293 MoveOutDetector(MoveOutDetector &&other) noexcept : initialized(other.initialized) {
295 other.initialized =
false;
297 bool initialized =
true;
299 py::class_<MoveOutDetector>(m,
"MoveOutDetector",
"Class with move tracking")
301 .def_readonly(
"initialized", &MoveOutDetector::initialized);
303#ifdef PYBIND11_HAS_OPTIONAL
305 m.attr(
"has_optional") =
true;
307 using opt_int = std::optional<int>;
308 using opt_no_assign = std::optional<NoAssign>;
309 m.def(
"double_or_zero", [](
const opt_int &x) ->
int {
return x.value_or(0) * 2; });
310 m.def(
"half_or_none", [](
int x) -> opt_int {
return x != 0 ? opt_int(x / 2) : opt_int(); });
313 [](opt_int x) {
return x.value_or(42); },
314 py::arg_v(
"x", std::nullopt,
"None"));
317 [](
const opt_no_assign &x) {
return x ? x->value : 42; },
318 py::arg_v(
"x", std::nullopt,
"None"));
320 m.def(
"nodefer_none_optional", [](std::optional<int>) {
return true; });
321 m.def(
"nodefer_none_optional", [](
const py::none &) {
return false; });
324 py::class_<opt_holder>(m,
"OptionalHolder",
"Class with optional member")
326 .def_readonly(
"member", &opt_holder::member)
327 .def(
"member_initialized", &opt_holder::member_initialized);
330 pybind11::class_<opt_props>(m,
"OptionalProperties")
331 .def(pybind11::init<>())
332 .def_property_readonly(
"access_by_ref", &opt_props::access_by_ref)
333 .def_property_readonly(
"access_by_copy", &opt_props::access_by_copy);
336#ifdef PYBIND11_HAS_EXP_OPTIONAL
338 m.attr(
"has_exp_optional") =
true;
340 using exp_opt_int = std::experimental::optional<int>;
341 using exp_opt_no_assign = std::experimental::optional<NoAssign>;
342 m.def(
"double_or_zero_exp", [](
const exp_opt_int &x) ->
int {
return x.value_or(0) * 2; });
343 m.def(
"half_or_none_exp",
344 [](
int x) -> exp_opt_int {
return x ? exp_opt_int(x / 2) : exp_opt_int(); });
347 [](exp_opt_int x) {
return x.value_or(42); },
348 py::arg_v(
"x", std::experimental::nullopt,
"None"));
350 "test_no_assign_exp",
351 [](
const exp_opt_no_assign &x) {
return x ? x->value : 42; },
352 py::arg_v(
"x", std::experimental::nullopt,
"None"));
355 py::class_<opt_exp_holder>(m,
"OptionalExpHolder",
"Class with optional member")
357 .def_readonly(
"member", &opt_exp_holder::member)
358 .def(
"member_initialized", &opt_exp_holder::member_initialized);
361 pybind11::class_<opt_exp_props>(m,
"OptionalExpProperties")
362 .def(pybind11::init<>())
363 .def_property_readonly(
"access_by_ref", &opt_exp_props::access_by_ref)
364 .def_property_readonly(
"access_by_copy", &opt_exp_props::access_by_copy);
367#if defined(PYBIND11_TEST_BOOST)
369 m.attr(
"has_boost_optional") =
true;
371 using boost_opt_int = boost::optional<int>;
372 using boost_opt_no_assign = boost::optional<NoAssign>;
373 m.def(
"double_or_zero_boost", [](
const boost_opt_int &x) ->
int {
return x.value_or(0) * 2; });
374 m.def(
"half_or_none_boost",
375 [](
int x) -> boost_opt_int {
return x != 0 ? boost_opt_int(x / 2) : boost_opt_int(); });
377 "test_nullopt_boost",
378 [](boost_opt_int x) {
return x.value_or(42); },
379 py::arg_v(
"x", boost::none,
"None"));
381 "test_no_assign_boost",
382 [](
const boost_opt_no_assign &x) {
return x ? x->value : 42; },
383 py::arg_v(
"x", boost::none,
"None"));
386 py::class_<opt_boost_holder>(m,
"OptionalBoostHolder",
"Class with optional member")
388 .def_readonly(
"member", &opt_boost_holder::member)
389 .def(
"member_initialized", &opt_boost_holder::member_initialized);
392 pybind11::class_<opt_boost_props>(m,
"OptionalBoostProperties")
393 .def(pybind11::init<>())
394 .def_property_readonly(
"access_by_ref", &opt_boost_props::access_by_ref)
395 .def_property_readonly(
"access_by_copy", &opt_boost_props::access_by_copy);
401 m.def(
"double_or_zero_refsensitive",
402 [](
const refsensitive_opt_int &x) ->
int {
return (x ? x.value() : 0) * 2; });
403 m.def(
"half_or_none_refsensitive", [](
int x) -> refsensitive_opt_int {
404 return x != 0 ? refsensitive_opt_int(x / 2) : refsensitive_opt_int();
407 "test_nullopt_refsensitive",
409 [](refsensitive_opt_int x) {
return x ? x.value() : 42; },
410 py::arg_v(
"x", refsensitive_opt_int(),
"None"));
412 "test_no_assign_refsensitive",
413 [](
const refsensitive_opt_no_assign &x) {
return x ? x->value : 42; },
414 py::arg_v(
"x", refsensitive_opt_no_assign(),
"None"));
417 py::class_<opt_refsensitive_holder>(
418 m,
"OptionalRefSensitiveHolder",
"Class with optional member")
420 .def_readonly(
"member", &opt_refsensitive_holder::member)
421 .def(
"member_initialized", &opt_refsensitive_holder::member_initialized);
424 pybind11::class_<opt_refsensitive_props>(m,
"OptionalRefSensitiveProperties")
425 .def(pybind11::init<>())
426 .def_property_readonly(
"access_by_ref", &opt_refsensitive_props::access_by_ref)
427 .def_property_readonly(
"access_by_copy", &opt_refsensitive_props::access_by_copy);
429#ifdef PYBIND11_HAS_FILESYSTEM
431 m.attr(
"has_filesystem") =
true;
432 m.def(
"parent_path", [](
const std::filesystem::path &p) {
return p.parent_path(); });
435#ifdef PYBIND11_TEST_VARIANT
436 static_assert(std::is_same<py::detail::variant_caster_visitor::result_type, py::handle>::value,
437 "visitor::result_type is required by boost::variant in C++11 mode");
440 using result_type =
const char *;
442 result_type operator()(
int) {
return "int"; }
443 result_type operator()(
const std::string &) {
return "std::string"; }
444 result_type operator()(
double) {
return "double"; }
445 result_type operator()(std::nullptr_t) {
return "std::nullptr_t"; }
446# if defined(PYBIND11_HAS_VARIANT)
447 result_type operator()(std::monostate) {
return "std::monostate"; }
452 m.def(
"load_variant", [](
const variant<int, std::string, double, std::nullptr_t> &v) {
453 return py::detail::visit_helper<variant>::call(visitor(), v);
455 m.def(
"load_variant_2pass", [](variant<double, int> v) {
456 return py::detail::visit_helper<variant>::call(visitor(), v);
458 m.def(
"cast_variant", []() {
459 using V = variant<int, std::string>;
460 return py::make_tuple(V(5), V(
"Hello"));
463# if defined(PYBIND11_HAS_VARIANT)
465 m.def(
"load_monostate_variant",
466 [](
const variant<std::monostate, int, std::string> &v) ->
const char * {
467 return py::detail::visit_helper<variant>::call(visitor(), v);
469 m.def(
"cast_monostate_variant", []() {
470 using V = variant<std::monostate, int, std::string>;
471 return py::make_tuple(V{}, V(5), V(
"Hello"));
478 m.def(
"tpl_ctor_vector", [](std::vector<TplCtorClass> &) {});
479 m.def(
"tpl_ctor_map", [](std::unordered_map<TplCtorClass, TplCtorClass> &) {});
480 m.def(
"tpl_ctor_set", [](std::unordered_set<TplCtorClass> &) {});
481#if defined(PYBIND11_HAS_OPTIONAL)
482 m.def(
"tpl_constr_optional", [](std::optional<TplCtorClass> &) {});
484#if defined(PYBIND11_HAS_EXP_OPTIONAL)
485 m.def(
"tpl_constr_optional_exp", [](std::experimental::optional<TplCtorClass> &) {});
487#if defined(PYBIND11_TEST_BOOST)
488 m.def(
"tpl_constr_optional_boost", [](boost::optional<TplCtorClass> &) {});
493 m.def(
"return_vec_of_reference_wrapper", [](std::reference_wrapper<UserType> p4) {
494 static UserType p1{1}, p2{2}, p3{3};
495 return std::vector<std::reference_wrapper<UserType>>{
496 std::ref(p1), std::ref(p2), std::ref(p3), p4};
501 "stl_pass_by_pointer", [](std::vector<int> *v) {
return *v; },
"v"_a =
nullptr);
504 m.def(
"func_with_string_or_vector_string_arg_overload",
505 [](
const std::vector<std::string> &) {
return 1; });
506 m.def(
"func_with_string_or_vector_string_arg_overload",
507 [](
const std::list<std::string> &) {
return 2; });
508 m.def(
"func_with_string_or_vector_string_arg_overload", [](
const std::string &) {
return 3; });
513 Placeholder(
const Placeholder &) =
delete;
516 py::class_<Placeholder>(m,
"Placeholder");
520 "test_stl_ownership",
522 std::vector<Placeholder *> result;
523 result.push_back(
new Placeholder());
526 py::return_value_policy::take_ownership);
528 m.def(
"array_cast_sequence", [](std::array<int, 3> x) {
return x; });
531 struct Issue1561Inner {
534 struct Issue1561Outer {
535 std::vector<Issue1561Inner>
list;
538 py::class_<Issue1561Inner>(m,
"Issue1561Inner")
539 .def(py::init<std::string>())
540 .def_readwrite(
"data", &Issue1561Inner::data);
542 py::class_<Issue1561Outer>(m,
"Issue1561Outer")
544 .def_readwrite(
"list", &Issue1561Outer::list);
547 "return_vector_bool_raw_ptr",
548 []() {
return new std::vector<bool>(4513); },
550 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.