Introduce PYBIND11_TYPE_CASTER_ODR_GUARD_ON (but not set automatically).

This commit is contained in:
Ralf W. Grosse-Kunstleve 2022-06-21 14:53:15 -07:00
parent 47c4e7939e
commit d390918d88
2 changed files with 57 additions and 22 deletions

View File

@ -47,6 +47,8 @@ class type_caster_for_class_ : public type_caster_base<T> {};
template <typename type, typename SFINAE = void> template <typename type, typename SFINAE = void>
class type_caster : public type_caster_for_class_<type> {}; class type_caster : public type_caster_for_class_<type> {};
#ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_ON
inline std::unordered_map<std::type_index, std::string> &odr_guard_registry() { inline std::unordered_map<std::type_index, std::string> &odr_guard_registry() {
static std::unordered_map<std::type_index, std::string> reg; static std::unordered_map<std::type_index, std::string> reg;
return reg; return reg;
@ -54,15 +56,15 @@ inline std::unordered_map<std::type_index, std::string> &odr_guard_registry() {
inline const char *cpp_version_in_use() { inline const char *cpp_version_in_use() {
return return
#if defined(PYBIND11_CPP20) # if defined(PYBIND11_CPP20)
"C++20"; "C++20";
#elif defined(PYBIND11_CPP17) # elif defined(PYBIND11_CPP17)
"C++17"; "C++17";
#elif defined(PYBIND11_CPP14) # elif defined(PYBIND11_CPP14)
"C++14"; "C++14";
#else # else
"C++11"; "C++11";
#endif # endif
} }
inline const char *source_file_line_basename(const char *sfl) { inline const char *source_file_line_basename(const char *sfl) {
@ -80,12 +82,12 @@ namespace {
template <typename IntrinsicType> template <typename IntrinsicType>
bool odr_guard_impl(const std::type_index &it_ti, const char *source_file_line) { bool odr_guard_impl(const std::type_index &it_ti, const char *source_file_line) {
// std::cout cannot be used here: static initialization could be incomplete. // std::cout cannot be used here: static initialization could be incomplete.
#define PYBIND11_DETAIL_ODR_GUARD_IMPL_PRINTF_OFF # define PYBIND11_DETAIL_ODR_GUARD_IMPL_PRINTF_OFF
#ifdef PYBIND11_DETAIL_ODR_GUARD_IMPL_PRINTF_ON # ifdef PYBIND11_DETAIL_ODR_GUARD_IMPL_PRINTF_ON
fprintf( fprintf(
stdout, "\nODR_GUARD_IMPL %s %s\n", type_id<IntrinsicType>().c_str(), source_file_line); stdout, "\nODR_GUARD_IMPL %s %s\n", type_id<IntrinsicType>().c_str(), source_file_line);
fflush(stdout); fflush(stdout);
#endif # endif
std::string sflbn_str{source_file_line_basename(source_file_line)}; std::string sflbn_str{source_file_line_basename(source_file_line)};
auto ins = odr_guard_registry().insert({it_ti, source_file_line}); auto ins = odr_guard_registry().insert({it_ti, source_file_line});
auto reg_iter = ins.first; auto reg_iter = ins.first;
@ -99,13 +101,13 @@ bool odr_guard_impl(const std::type_index &it_ti, const char *source_file_line)
+ "): pybind11::detail::type_caster<" + type_id<IntrinsicType>() + "): pybind11::detail::type_caster<" + type_id<IntrinsicType>()
+ ">: SourceLocation1=\"" + reg_iter->second + ">: SourceLocation1=\"" + reg_iter->second
+ "\", SourceLocation2=\"" + source_file_line + "\""); + "\", SourceLocation2=\"" + source_file_line + "\"");
#define PYBIND11_TYPE_CASTER_ODR_GUARD_THROW_OFF # define PYBIND11_TYPE_CASTER_ODR_GUARD_THROW_OFF
#ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_THROW_ON # ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_THROW_ON
throw err; throw err;
#else # else
fprintf(stderr, "\nDISABLED std::system_error: %s\n", err.what()); fprintf(stderr, "\nDISABLED std::system_error: %s\n", err.what());
fflush(stderr); fflush(stderr);
#endif # endif
} }
return true; return true;
} }
@ -127,9 +129,18 @@ int type_caster_odr_guard<IntrinsicType>::translation_unit_local = []() {
template <typename type> template <typename type>
using make_caster = type_caster_odr_guard<intrinsic_t<type>>; using make_caster = type_caster_odr_guard<intrinsic_t<type>>;
#define PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(...) \ # define PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(...) \
if (::pybind11::detail::make_caster<__VA_ARGS__>::translation_unit_local) { \ if (::pybind11::detail::make_caster<__VA_ARGS__>::translation_unit_local) { \
} }
#else // !PYBIND11_TYPE_CASTER_ODR_GUARD_ON
template <typename type>
using make_caster = type_caster<intrinsic_t<type>>;
# define PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(...)
#endif
template <typename T> template <typename T>
struct type_uses_smart_holder_type_caster { struct type_uses_smart_holder_type_caster {
@ -187,14 +198,13 @@ public:
explicit operator std::reference_wrapper<type>() { return cast_op<type &>(subcaster); } explicit operator std::reference_wrapper<type>() { return cast_op<type &>(subcaster); }
}; };
#define PYBIND11_TYPE_CASTER(type, py_name) \ #define PYBIND11_DETAIL_TYPE_CASTER_HEAD(type, py_name) \
protected: \ protected: \
type value; \ type value; \
\ \
public: \ public: \
static constexpr auto name = py_name; \ static constexpr auto name = py_name;
static constexpr auto source_file_line \ #define PYBIND11_DETAIL_TYPE_CASTER_TAIL(type) \
= ::pybind11::detail::tu_local_const_name(__FILE__ ":" PYBIND11_TOSTRING(__LINE__)); \
template <typename T_, \ template <typename T_, \
::pybind11::detail::enable_if_t< \ ::pybind11::detail::enable_if_t< \
std::is_same<type, ::pybind11::detail::remove_cv_t<T_>>::value, \ std::is_same<type, ::pybind11::detail::remove_cv_t<T_>>::value, \
@ -216,6 +226,22 @@ public:
template <typename T_> \ template <typename T_> \
using cast_op_type = ::pybind11::detail::movable_cast_op_type<T_> using cast_op_type = ::pybind11::detail::movable_cast_op_type<T_>
#ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_ON
# define PYBIND11_TYPE_CASTER(type, py_name) \
PYBIND11_DETAIL_TYPE_CASTER_HEAD(type, py_name) \
static constexpr auto source_file_line \
= ::pybind11::detail::tu_local_const_name(__FILE__ ":" PYBIND11_TOSTRING(__LINE__)); \
PYBIND11_DETAIL_TYPE_CASTER_TAIL(type)
#else // !PYBIND11_TYPE_CASTER_ODR_GUARD_ON
# define PYBIND11_TYPE_CASTER(type, py_name) \
PYBIND11_DETAIL_TYPE_CASTER_HEAD(type, py_name) \
PYBIND11_DETAIL_TYPE_CASTER_TAIL(type)
#endif
template <typename CharT> template <typename CharT>
using is_std_char_type = any_of<std::is_same<CharT, char>, /* std::string */ using is_std_char_type = any_of<std::is_same<CharT, char>, /* std::string */
#if defined(PYBIND11_HAS_U8STRING) #if defined(PYBIND11_HAS_U8STRING)

View File

@ -904,6 +904,9 @@ struct polymorphic_type_hook : public polymorphic_type_hook_base<itype> {};
PYBIND11_NAMESPACE_BEGIN(detail) PYBIND11_NAMESPACE_BEGIN(detail)
#define PYBIND11_TYPE_CASTER_ODR_GUARD_ON
#ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_ON
namespace { namespace {
template <size_t N, typename... Ts> template <size_t N, typename... Ts>
@ -920,9 +923,15 @@ constexpr tu_local_descr<0> tu_local_const_name(char const (&)[1]) { return {};
} // namespace } // namespace
#define PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE \ # define PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE \
static constexpr auto source_file_line \ static constexpr auto source_file_line \
= ::pybind11::detail::tu_local_const_name(__FILE__ ":" PYBIND11_TOSTRING(__LINE__)); = ::pybind11::detail::tu_local_const_name(__FILE__ ":" PYBIND11_TOSTRING(__LINE__));
#else // !PYBIND11_TYPE_CASTER_ODR_GUARD_ON
# define PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE
#endif
/// Generic type caster for objects stored on the heap /// Generic type caster for objects stored on the heap
template <typename type> template <typename type>