mirror of
https://github.com/pybind/pybind11.git
synced 2025-01-19 17:32:37 +00:00
Move cpp_version_in_use() from cast.h to pybind11_tests.cpp
This commit is contained in:
parent
369a3905fa
commit
a34771aeda
@ -14,6 +14,7 @@
|
|||||||
#include "detail/descr.h"
|
#include "detail/descr.h"
|
||||||
#include "detail/smart_holder_sfinae_hooks_only.h"
|
#include "detail/smart_holder_sfinae_hooks_only.h"
|
||||||
#include "detail/type_caster_base.h"
|
#include "detail/type_caster_base.h"
|
||||||
|
#include "detail/type_caster_odr_guard.h"
|
||||||
#include "detail/typeid.h"
|
#include "detail/typeid.h"
|
||||||
#include "pytypes.h"
|
#include "pytypes.h"
|
||||||
|
|
||||||
@ -49,69 +50,8 @@ class type_caster : public type_caster_for_class_<type> {};
|
|||||||
|
|
||||||
#ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
#ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
||||||
|
|
||||||
inline std::unordered_map<std::type_index, std::string> &odr_guard_registry() {
|
|
||||||
static std::unordered_map<std::type_index, std::string> reg;
|
|
||||||
return reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char *cpp_version_in_use() {
|
|
||||||
return
|
|
||||||
# if defined(PYBIND11_CPP20)
|
|
||||||
"C++20";
|
|
||||||
# elif defined(PYBIND11_CPP17)
|
|
||||||
"C++17";
|
|
||||||
# elif defined(PYBIND11_CPP14)
|
|
||||||
"C++14";
|
|
||||||
# else
|
|
||||||
"C++11";
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char *source_file_line_basename(const char *sfl) {
|
|
||||||
unsigned i_base = 0;
|
|
||||||
for (unsigned i = 0; sfl[i] != '\0'; i++) {
|
|
||||||
if (sfl[i] == '/' || sfl[i] == '\\') {
|
|
||||||
i_base = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sfl + i_base;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <typename IntrinsicType>
|
|
||||||
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.
|
|
||||||
# define PYBIND11_DETAIL_ODR_GUARD_IMPL_PRINTF_OFF
|
|
||||||
# ifdef PYBIND11_DETAIL_ODR_GUARD_IMPL_PRINTF_ON
|
|
||||||
fprintf(
|
|
||||||
stdout, "\nODR_GUARD_IMPL %s %s\n", type_id<IntrinsicType>().c_str(), source_file_line);
|
|
||||||
fflush(stdout);
|
|
||||||
# endif
|
|
||||||
std::string sflbn_str{source_file_line_basename(source_file_line)};
|
|
||||||
auto ins = odr_guard_registry().insert({it_ti, source_file_line});
|
|
||||||
auto reg_iter = ins.first;
|
|
||||||
auto added = ins.second;
|
|
||||||
if (!added
|
|
||||||
&& strcmp(source_file_line_basename(reg_iter->second.c_str()),
|
|
||||||
source_file_line_basename(source_file_line))
|
|
||||||
!= 0) {
|
|
||||||
std::system_error err(std::make_error_code(std::errc::state_not_recoverable),
|
|
||||||
"ODR VIOLATION DETECTED (" + std::string(cpp_version_in_use())
|
|
||||||
+ "): pybind11::detail::type_caster<" + type_id<IntrinsicType>()
|
|
||||||
+ ">: SourceLocation1=\"" + reg_iter->second
|
|
||||||
+ "\", SourceLocation2=\"" + source_file_line + "\"");
|
|
||||||
# define PYBIND11_TYPE_CASTER_ODR_GUARD_THROW_OFF
|
|
||||||
# ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_THROW_ON
|
|
||||||
throw err;
|
|
||||||
# else
|
|
||||||
fprintf(stderr, "\nDISABLED std::system_error: %s\n", err.what());
|
|
||||||
fflush(stderr);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename IntrinsicType>
|
template <typename IntrinsicType>
|
||||||
struct type_caster_odr_guard : type_caster<IntrinsicType> {
|
struct type_caster_odr_guard : type_caster<IntrinsicType> {
|
||||||
static int translation_unit_local;
|
static int translation_unit_local;
|
||||||
@ -129,17 +69,11 @@ 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(...) \
|
|
||||||
if (::pybind11::detail::make_caster<__VA_ARGS__>::translation_unit_local) { \
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // !PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
#else // !PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
||||||
|
|
||||||
template <typename type>
|
template <typename type>
|
||||||
using make_caster = type_caster<intrinsic_t<type>>;
|
using make_caster = type_caster<intrinsic_t<type>>;
|
||||||
|
|
||||||
# define PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(...)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "descr.h"
|
#include "descr.h"
|
||||||
#include "internals.h"
|
#include "internals.h"
|
||||||
|
#include "type_caster_odr_guard.h"
|
||||||
#include "typeid.h"
|
#include "typeid.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -904,40 +905,6 @@ struct polymorphic_type_hook : public polymorphic_type_hook_base<itype> {};
|
|||||||
|
|
||||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
#if !defined(PYBIND11_TYPE_CASTER_ODR_GUARD_ON) && !defined(PYBIND11_TYPE_CASTER_ODR_GUARD_OFF) \
|
|
||||||
&& (defined(_MSC_VER) || defined(PYBIND11_CPP20) \
|
|
||||||
|| (defined(PYBIND11_CPP17) && defined(__clang__)))
|
|
||||||
# define PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
template <size_t N, typename... Ts>
|
|
||||||
struct tu_local_descr : descr<N, Ts...> {
|
|
||||||
using descr_t = descr<N, Ts...>;
|
|
||||||
using descr_t::descr_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <size_t N>
|
|
||||||
constexpr tu_local_descr<N - 1> tu_local_const_name(char const (&text)[N]) {
|
|
||||||
return tu_local_descr<N - 1>(text);
|
|
||||||
}
|
|
||||||
constexpr tu_local_descr<0> tu_local_const_name(char const (&)[1]) { return {}; }
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
# define PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE \
|
|
||||||
static constexpr auto source_file_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>
|
||||||
class type_caster_base : public type_caster_generic {
|
class type_caster_base : public type_caster_generic {
|
||||||
|
118
include/pybind11/detail/type_caster_odr_guard.h
Normal file
118
include/pybind11/detail/type_caster_odr_guard.h
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// Copyright (c) 2022 The Pybind Development Team.
|
||||||
|
// All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(PYBIND11_TYPE_CASTER_ODR_GUARD_ON) && !defined(PYBIND11_TYPE_CASTER_ODR_GUARD_OFF) \
|
||||||
|
&& (defined(_MSC_VER) || defined(PYBIND11_CPP20) \
|
||||||
|
|| (defined(PYBIND11_CPP17) && defined(__clang__)))
|
||||||
|
# define PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
||||||
|
|
||||||
|
# define PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE
|
||||||
|
|
||||||
|
# define PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(...)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
# include "common.h"
|
||||||
|
# include "descr.h"
|
||||||
|
# include "typeid.h"
|
||||||
|
|
||||||
|
# include <array>
|
||||||
|
# include <cstring>
|
||||||
|
# include <functional>
|
||||||
|
# include <iosfwd>
|
||||||
|
# include <iterator>
|
||||||
|
# include <memory>
|
||||||
|
# include <string>
|
||||||
|
# include <system_error>
|
||||||
|
# include <tuple>
|
||||||
|
# include <type_traits>
|
||||||
|
# include <typeindex>
|
||||||
|
# include <unordered_map>
|
||||||
|
# include <utility>
|
||||||
|
# include <vector>
|
||||||
|
|
||||||
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
|
inline std::unordered_map<std::type_index, std::string> &odr_guard_registry() {
|
||||||
|
static std::unordered_map<std::type_index, std::string> reg;
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char *source_file_line_basename(const char *sfl) {
|
||||||
|
unsigned i_base = 0;
|
||||||
|
for (unsigned i = 0; sfl[i] != '\0'; i++) {
|
||||||
|
if (sfl[i] == '/' || sfl[i] == '\\') {
|
||||||
|
i_base = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sfl + i_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename IntrinsicType>
|
||||||
|
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.
|
||||||
|
# define PYBIND11_DETAIL_ODR_GUARD_IMPL_PRINTF_OFF
|
||||||
|
# ifdef PYBIND11_DETAIL_ODR_GUARD_IMPL_PRINTF_ON
|
||||||
|
fprintf(
|
||||||
|
stdout, "\nODR_GUARD_IMPL %s %s\n", type_id<IntrinsicType>().c_str(), source_file_line);
|
||||||
|
fflush(stdout);
|
||||||
|
# endif
|
||||||
|
std::string sflbn_str{source_file_line_basename(source_file_line)};
|
||||||
|
auto ins = odr_guard_registry().insert({it_ti, source_file_line});
|
||||||
|
auto reg_iter = ins.first;
|
||||||
|
auto added = ins.second;
|
||||||
|
if (!added
|
||||||
|
&& strcmp(source_file_line_basename(reg_iter->second.c_str()),
|
||||||
|
source_file_line_basename(source_file_line))
|
||||||
|
!= 0) {
|
||||||
|
std::system_error err(std::make_error_code(std::errc::state_not_recoverable),
|
||||||
|
"ODR VIOLATION DETECTED: pybind11::detail::type_caster<"
|
||||||
|
+ type_id<IntrinsicType>() + ">: SourceLocation1=\""
|
||||||
|
+ reg_iter->second + "\", SourceLocation2=\"" + source_file_line
|
||||||
|
+ "\"");
|
||||||
|
# define PYBIND11_TYPE_CASTER_ODR_GUARD_THROW_OFF
|
||||||
|
# ifdef PYBIND11_TYPE_CASTER_ODR_GUARD_THROW_ON
|
||||||
|
throw err;
|
||||||
|
# else
|
||||||
|
fprintf(stderr, "\nDISABLED std::system_error: %s\n", err.what());
|
||||||
|
fflush(stderr);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <size_t N, typename... Ts>
|
||||||
|
struct tu_local_descr : descr<N, Ts...> {
|
||||||
|
using descr_t = descr<N, Ts...>;
|
||||||
|
using descr_t::descr_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
constexpr tu_local_descr<N - 1> tu_local_const_name(char const (&text)[N]) {
|
||||||
|
return tu_local_descr<N - 1>(text);
|
||||||
|
}
|
||||||
|
constexpr tu_local_descr<0> tu_local_const_name(char const (&)[1]) { return {}; }
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||||
|
|
||||||
|
# define PYBIND11_TYPE_CASTER_SOURCE_FILE_LINE \
|
||||||
|
static constexpr auto source_file_line \
|
||||||
|
= ::pybind11::detail::tu_local_const_name(__FILE__ ":" PYBIND11_TOSTRING(__LINE__));
|
||||||
|
|
||||||
|
# define PYBIND11_DETAIL_TYPE_CASTER_ACCESS_TRANSLATION_UNIT_LOCAL(...) \
|
||||||
|
if (::pybind11::detail::make_caster<__VA_ARGS__>::translation_unit_local) { \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -62,10 +62,23 @@ void bind_ConstructorStats(py::module_ &m) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *cpp_version_in_use() {
|
||||||
|
return
|
||||||
|
#if defined(PYBIND11_CPP20)
|
||||||
|
"C++20";
|
||||||
|
#elif defined(PYBIND11_CPP17)
|
||||||
|
"C++17";
|
||||||
|
#elif defined(PYBIND11_CPP14)
|
||||||
|
"C++14";
|
||||||
|
#else
|
||||||
|
"C++11";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
PYBIND11_MODULE(pybind11_tests, m) {
|
PYBIND11_MODULE(pybind11_tests, m) {
|
||||||
m.doc() = "pybind11 test module";
|
m.doc() = "pybind11 test module";
|
||||||
|
|
||||||
m.attr("cpp_version_in_use") = py::detail::cpp_version_in_use();
|
m.attr("cpp_version_in_use") = cpp_version_in_use();
|
||||||
m.attr("PYBIND11_INTERNALS_ID") = PYBIND11_INTERNALS_ID;
|
m.attr("PYBIND11_INTERNALS_ID") = PYBIND11_INTERNALS_ID;
|
||||||
|
|
||||||
bind_ConstructorStats(m);
|
bind_ConstructorStats(m);
|
||||||
|
Loading…
Reference in New Issue
Block a user