#include "pybind11.h" #include #include #include #include #include #include #include namespace pkbind { template struct type_caster> { std::array data; template static handle cast(U&& src, return_value_policy policy, handle parent) { auto list = pkbind::list(); for(auto&& item: src) { list.append(pkbind::cast(std::move(item), policy, parent)); } return list; } bool load(handle src, bool convert) { if(!isinstance(src)) { return false; } auto list = src.cast(); if(list.size() != N) { return false; } for(int i = 0; i < N; ++i) { type_caster caster; if(!caster.load(list[i], convert)) { return false; } data[i] = std::move(caster.value()); } return true; } std::array& value() { return data; } constexpr inline static bool is_temporary_v = true; }; template constexpr bool is_py_list_like_v = false; template constexpr bool is_py_list_like_v> = true; template constexpr bool is_py_list_like_v> = true; template constexpr bool is_py_list_like_v> = true; template <> struct type_caster> { std::vector data; template static object cast(U&& src, return_value_policy policy, handle parent) { auto list = pkbind::list(); for(auto&& item: src) { list.append(pkbind::cast(bool(item), policy, parent)); } return list; } bool load(handle src, bool convert) { if(!isinstance(src)) { return false; } auto list = src.cast(); data.clear(); data.reserve(list.size()); for(auto item: list) { type_caster caster; if(!caster.load(item, convert)) { return false; } data.push_back(caster.value()); } return true; } std::vector& value() { return data; } constexpr inline static bool is_temporary_v = true; }; template struct type_caster>> { T data; template static object cast(U&& src, return_value_policy policy, handle parent) { auto list = pkbind::list(); for(auto&& item: src) { list.append(pkbind::cast(std::move(item), policy, parent)); } return list; } bool load(handle src, bool convert) { if(!isinstance(src)) { return false; } auto list = src.cast(); for(auto item: list) { type_caster caster; if(!caster.load(item, convert)) { return false; } data.push_back(std::move(caster.value())); } return true; } T& value() { return data; } constexpr inline static bool is_temporary_v = true; }; template constexpr bool is_py_map_like_v = false; template constexpr bool is_py_map_like_v> = true; template constexpr bool is_py_map_like_v> = true; template struct type_caster>> { T data; template static object cast(U&& src, return_value_policy policy, handle parent) { auto dict = pkbind::dict(); for(auto&& [key, value]: src) { dict[pkbind::cast(std::move(key), policy, parent)] = pkbind::cast(std::move(value), policy, parent); } return dict; } bool load(handle src, bool convert) { if(!isinstance(src)) { return false; } auto dict = src.cast(); for(auto item: dict) { type_caster key_caster; if(!key_caster.load(item.first, convert)) { return false; } type_caster value_caster; if(!value_caster.load(item.second, convert)) { return false; } data.try_emplace(std::move(key_caster.value()), std::move(value_caster.value())); } return true; } T& value() { return data; } constexpr inline static bool is_temporary_v = true; }; } // namespace pkbind