#pragma once #include "instance.h" #include "builtins.h" #include "type_traits.h" namespace pybind11 { using pkpy::is_floating_point_v; using pkpy::is_integral_v; template constexpr inline bool is_string_v = std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v; template constexpr bool is_pyobject_v = std::is_base_of_v; template struct type_caster; template <> struct type_caster { bool value; bool load(const handle& src, bool) { if(isinstance(src)) { value = pkpy::_py_cast(vm, src.ptr()); return true; } return false; } static handle cast(bool src, return_value_policy, handle) { return src ? vm->True : vm->False; } }; template struct type_caster>> { T value; bool load(const handle& src, bool convert) { if(isinstance(src)) { value = pkpy::_py_cast(vm, src.ptr()); return true; } return false; } static handle cast(T src, return_value_policy, handle) { return pkpy::py_var(vm, src); } }; template struct type_caster>> { T value; bool load(const handle& src, bool convert) { if(isinstance(src)) { value = pkpy::_py_cast(vm, src.ptr()); return true; } if(convert && isinstance(src)) { value = pkpy::_py_cast(vm, src.ptr()); return true; } return false; } static handle cast(T src, return_value_policy, handle) { return pkpy::py_var(vm, src); } }; template struct type_caster>> { T value; bool load(const handle& src, bool) { if(isinstance(src)) { // FIXME: support other kinds of string value = pkpy::_py_cast(vm, src.ptr()); return true; } return false; } static handle cast(const std::string& src, return_value_policy, handle) { return pkpy::py_var(vm, src); } }; template struct type_caster>> { T value; bool load(const handle& src, bool) { if(isinstance(src)) { value = reinterpret_borrow(src); return true; } return false; } template static handle cast(U&& src, return_value_policy, handle) { return std::forward(src); } }; template struct type_caster { value_wrapper value; using underlying_type = std::remove_pointer_t; bool load(handle src, bool convert) { if(isinstance(src)) { auto& i = _builtin_cast(src); value.pointer = &i.cast(); return true; } return false; } template static handle cast(U&& value, return_value_policy policy, const handle& parent = handle()) { // TODO: support implicit cast const auto& info = typeid(underlying_type); bool existed = vm->_cxx_typeid_map.find(info) != vm->_cxx_typeid_map.end(); if(existed) { auto type = vm->_cxx_typeid_map[info]; return instance::create(std::forward(value), type, policy, parent.ptr()); } vm->TypeError("type not registered"); } }; template struct type_caster || std::is_reference_v>> { using underlying = std::conditional_t, std::remove_pointer_t, std::remove_reference_t>; struct wrapper { type_caster caster; operator T () { if constexpr(std::is_pointer_v) { return caster.value.pointer; } else { return caster.value; } } }; wrapper value; bool load(const handle& src, bool convert) { return value.caster.load(src, convert); } template static handle cast(U&& value, return_value_policy policy, const handle& parent) { return type_caster::cast(std::forward(value), policy, parent); } }; } // namespace pybind11