#pragma once #include "instance.h" #include "accessor.h" namespace pybind11::impl { 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; template constexpr bool is_pointer_v = std::is_pointer_v && !std::is_same_v && !std::is_same_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)) { auto& str = src._as(); if constexpr(std::is_same_v) { value = str; } else if constexpr(std::is_same_v) { value = str; } else if constexpr(std::is_same_v) { value = str.c_str(); } return true; } return false; } template static handle cast(U&& src, return_value_policy, handle) { return str(std::forward(src)); } }; template struct type_caster>> { T value; bool load(const handle& src, bool) { if(isinstance(src)) { value = src; return true; } return false; } static handle cast(const handle& src, return_value_policy, handle) { return src; } }; template struct type_caster { struct value_wrapper { T* pointer; operator T& () { return *pointer; } }; value_wrapper value; using underlying_type = std::remove_pointer_t; bool load(handle src, bool convert) { if(isinstance(src)) { auto& i = src._as(); value.pointer = &i._as(); return true; } return false; } template static handle cast(U&& value, return_value_policy policy, const handle& parent = handle()) { const auto& info = typeid(underlying_type); auto type = type_visitor::type(); return instance::create(std::forward(value), type, policy, parent.ptr()); // TODO: support implicit cast } }; template struct type_caster || std::is_reference_v>> { using underlying = std::remove_cv_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