mirror of
https://github.com/pybind/pybind11.git
synced 2025-01-19 17:32:37 +00:00
Work scr_loc
into descr
This commit is contained in:
parent
38c25655b7
commit
44966dab16
@ -20,21 +20,69 @@ PYBIND11_NAMESPACE_BEGIN(detail)
|
|||||||
# define PYBIND11_DESCR_CONSTEXPR const
|
# define PYBIND11_DESCR_CONSTEXPR const
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// * MSVC 2017 does not support __builtin_FILE(), __builtin_LINE().
|
||||||
|
// * Intel 2021.6.0.20220226 (g++ 9.4 mode) __builtin_LINE() is unreliable
|
||||||
|
// (line numbers vary between translation units).
|
||||||
|
#if !defined(PYBIND11_DETAIL_DESCR_SRC_LOC_ON) && !defined(PYBIND11_DETAIL_DESCR_SRC_LOC_OFF) \
|
||||||
|
&& !defined(__INTEL_COMPILER) \
|
||||||
|
&& ((defined(_MSC_VER) && _MSC_VER >= 1920) || defined(PYBIND11_CPP17))
|
||||||
|
# define PYBIND11_DETAIL_DESCR_SRC_LOC_ON
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PYBIND11_DETAIL_DESCR_SRC_LOC_ON
|
||||||
|
|
||||||
|
struct src_loc {
|
||||||
|
const char *file;
|
||||||
|
unsigned line;
|
||||||
|
|
||||||
|
constexpr src_loc(const char *file, unsigned line) : file(file), line(line) {}
|
||||||
|
|
||||||
|
static constexpr src_loc here(const char *file = __builtin_FILE(),
|
||||||
|
unsigned line = __builtin_LINE()) {
|
||||||
|
return src_loc(file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr src_loc if_known_or(const src_loc &other) const {
|
||||||
|
if (file != nullptr) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
return other;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
struct src_loc {
|
||||||
|
constexpr src_loc(const char *, unsigned) {}
|
||||||
|
|
||||||
|
static constexpr src_loc here(const char * = nullptr, unsigned = 0) {
|
||||||
|
return src_loc(nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr src_loc if_known_or(const src_loc &) const { return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Concatenate type signatures at compile time */
|
/* Concatenate type signatures at compile time */
|
||||||
template <size_t N, typename... Ts>
|
template <size_t N, typename... Ts>
|
||||||
struct descr {
|
struct descr {
|
||||||
char text[N + 1]{'\0'};
|
char text[N + 1]{'\0'};
|
||||||
|
src_loc sloc;
|
||||||
|
|
||||||
constexpr descr() = default;
|
explicit constexpr descr(src_loc sloc) : sloc(sloc) {}
|
||||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
constexpr descr(char const (&s)[N + 1]) : descr(s, make_index_sequence<N>()) {}
|
constexpr descr(char const (&s)[N + 1], src_loc sloc = src_loc::here())
|
||||||
|
: descr(s, make_index_sequence<N>(), sloc) {}
|
||||||
|
|
||||||
template <size_t... Is>
|
template <size_t... Is>
|
||||||
constexpr descr(char const (&s)[N + 1], index_sequence<Is...>) : text{s[Is]..., '\0'} {}
|
constexpr descr(char const (&s)[N + 1], index_sequence<Is...>, src_loc sloc = src_loc::here())
|
||||||
|
: text{s[Is]..., '\0'}, sloc(sloc) {}
|
||||||
|
|
||||||
template <typename... Chars>
|
template <typename... Chars>
|
||||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
constexpr descr(char c, Chars... cs) : text{c, static_cast<char>(cs)..., '\0'} {}
|
constexpr descr(src_loc sloc, char c, Chars... cs)
|
||||||
|
: text{c, static_cast<char>(cs)..., '\0'}, sloc(sloc) {}
|
||||||
|
|
||||||
static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() {
|
static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() {
|
||||||
return {{&typeid(Ts)..., nullptr}};
|
return {{&typeid(Ts)..., nullptr}};
|
||||||
@ -47,7 +95,8 @@ constexpr descr<N1 + N2, Ts1..., Ts2...> plus_impl(const descr<N1, Ts1...> &a,
|
|||||||
index_sequence<Is1...>,
|
index_sequence<Is1...>,
|
||||||
index_sequence<Is2...>) {
|
index_sequence<Is2...>) {
|
||||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(b);
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(b);
|
||||||
return {a.text[Is1]..., b.text[Is2]...};
|
return descr<N1 + N2, Ts1..., Ts2...>{
|
||||||
|
a.sloc.if_known_or(b.sloc), a.text[Is1]..., b.text[Is2]...};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
|
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
|
||||||
@ -57,27 +106,31 @@ constexpr descr<N1 + N2, Ts1..., Ts2...> operator+(const descr<N1, Ts1...> &a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
constexpr descr<N - 1> const_name(char const (&text)[N]) {
|
constexpr descr<N - 1> const_name(char const (&text)[N], src_loc sloc = src_loc::here()) {
|
||||||
return descr<N - 1>(text);
|
return descr<N - 1>(text, sloc);
|
||||||
|
}
|
||||||
|
constexpr descr<0> const_name(char const (&)[1], src_loc sloc = src_loc::here()) {
|
||||||
|
return descr<0>(sloc);
|
||||||
}
|
}
|
||||||
constexpr descr<0> const_name(char const (&)[1]) { return {}; }
|
|
||||||
|
|
||||||
template <size_t Rem, size_t... Digits>
|
template <size_t Rem, size_t... Digits>
|
||||||
struct int_to_str : int_to_str<Rem / 10, Rem % 10, Digits...> {};
|
struct int_to_str : int_to_str<Rem / 10, Rem % 10, Digits...> {};
|
||||||
template <size_t... Digits>
|
template <size_t... Digits>
|
||||||
struct int_to_str<0, Digits...> {
|
struct int_to_str<0, Digits...> {
|
||||||
// WARNING: This only works with C++17 or higher.
|
// WARNING: This only works with C++17 or higher.
|
||||||
static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...);
|
static constexpr auto digits = descr<sizeof...(Digits)>(src_loc::here(), ('0' + Digits)...);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ternary description (like std::conditional)
|
// Ternary description (like std::conditional)
|
||||||
template <bool B, size_t N1, size_t N2>
|
template <bool B, size_t N1, size_t N2>
|
||||||
constexpr enable_if_t<B, descr<N1 - 1>> const_name(char const (&text1)[N1], char const (&)[N2]) {
|
constexpr enable_if_t<B, descr<N1 - 1>>
|
||||||
return const_name(text1);
|
const_name(char const (&text1)[N1], char const (&)[N2], src_loc sloc = src_loc::here()) {
|
||||||
|
return const_name(text1, sloc);
|
||||||
}
|
}
|
||||||
template <bool B, size_t N1, size_t N2>
|
template <bool B, size_t N1, size_t N2>
|
||||||
constexpr enable_if_t<!B, descr<N2 - 1>> const_name(char const (&)[N1], char const (&text2)[N2]) {
|
constexpr enable_if_t<!B, descr<N2 - 1>>
|
||||||
return const_name(text2);
|
const_name(char const (&)[N1], char const (&text2)[N2], src_loc sloc = src_loc::here()) {
|
||||||
|
return const_name(text2, sloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool B, typename T1, typename T2>
|
template <bool B, typename T1, typename T2>
|
||||||
@ -91,12 +144,13 @@ constexpr enable_if_t<!B, T2> const_name(const T1 &, const T2 &d) {
|
|||||||
|
|
||||||
template <size_t Size>
|
template <size_t Size>
|
||||||
auto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
|
auto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
|
||||||
|
// src_loc not tracked (irrelevant in this situation, at least at the moment).
|
||||||
return int_to_str<Size / 10, Size % 10>::digits;
|
return int_to_str<Size / 10, Size % 10>::digits;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
constexpr descr<1, Type> const_name() {
|
constexpr descr<1, Type> const_name(src_loc sloc = src_loc::here()) {
|
||||||
return {'%'};
|
return {sloc, '%'};
|
||||||
}
|
}
|
||||||
|
|
||||||
// If "_" is defined as a macro, py::detail::_ cannot be provided.
|
// If "_" is defined as a macro, py::detail::_ cannot be provided.
|
||||||
@ -106,16 +160,18 @@ constexpr descr<1, Type> const_name() {
|
|||||||
#ifndef _
|
#ifndef _
|
||||||
# define PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
|
# define PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
constexpr descr<N - 1> _(char const (&text)[N]) {
|
constexpr descr<N - 1> _(char const (&text)[N], src_loc sloc = src_loc::here()) {
|
||||||
return const_name<N>(text);
|
return const_name<N>(text, sloc);
|
||||||
}
|
}
|
||||||
template <bool B, size_t N1, size_t N2>
|
template <bool B, size_t N1, size_t N2>
|
||||||
constexpr enable_if_t<B, descr<N1 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
|
constexpr enable_if_t<B, descr<N1 - 1>>
|
||||||
return const_name<B, N1, N2>(text1, text2);
|
_(char const (&text1)[N1], char const (&text2)[N2], src_loc sloc = src_loc::here()) {
|
||||||
|
return const_name<B, N1, N2>(text1, text2, sloc);
|
||||||
}
|
}
|
||||||
template <bool B, size_t N1, size_t N2>
|
template <bool B, size_t N1, size_t N2>
|
||||||
constexpr enable_if_t<!B, descr<N2 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
|
constexpr enable_if_t<!B, descr<N2 - 1>>
|
||||||
return const_name<B, N1, N2>(text1, text2);
|
_(char const (&text1)[N1], char const (&text2)[N2], src_loc sloc = src_loc::here()) {
|
||||||
|
return const_name<B, N1, N2>(text1, text2, sloc);
|
||||||
}
|
}
|
||||||
template <bool B, typename T1, typename T2>
|
template <bool B, typename T1, typename T2>
|
||||||
constexpr enable_if_t<B, T1> _(const T1 &d1, const T2 &d2) {
|
constexpr enable_if_t<B, T1> _(const T1 &d1, const T2 &d2) {
|
||||||
@ -128,15 +184,16 @@ constexpr enable_if_t<!B, T2> _(const T1 &d1, const T2 &d2) {
|
|||||||
|
|
||||||
template <size_t Size>
|
template <size_t Size>
|
||||||
auto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
|
auto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
|
||||||
|
// src_loc not tracked (irrelevant in this situation, at least at the moment).
|
||||||
return const_name<Size>();
|
return const_name<Size>();
|
||||||
}
|
}
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
constexpr descr<1, Type> _() {
|
constexpr descr<1, Type> _(src_loc sloc = src_loc::here()) {
|
||||||
return const_name<Type>();
|
return const_name<Type>(sloc);
|
||||||
}
|
}
|
||||||
#endif // #ifndef _
|
#endif // #ifndef _
|
||||||
|
|
||||||
constexpr descr<0> concat() { return {}; }
|
constexpr descr<0> concat(src_loc sloc = src_loc::here()) { return descr<0>{sloc}; }
|
||||||
|
|
||||||
template <size_t N, typename... Ts>
|
template <size_t N, typename... Ts>
|
||||||
constexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {
|
constexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {
|
||||||
@ -151,7 +208,8 @@ constexpr auto concat(const descr<N, Ts...> &d, const Args &...args)
|
|||||||
|
|
||||||
template <size_t N, typename... Ts>
|
template <size_t N, typename... Ts>
|
||||||
constexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {
|
constexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {
|
||||||
return const_name("{") + descr + const_name("}");
|
// Ensure that src_loc of existing descr is used.
|
||||||
|
return const_name("{", src_loc{nullptr, 0}) + descr + const_name("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_NAMESPACE_END(detail)
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
|
@ -4,18 +4,16 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "descr.h"
|
||||||
|
|
||||||
// The type_caster ODR guard feature requires Translation-Unit-local entities
|
// The type_caster ODR guard feature requires Translation-Unit-local entities
|
||||||
// (https://en.cppreference.com/w/cpp/language/tu_local), a C++20 feature, but
|
// (https://en.cppreference.com/w/cpp/language/tu_local), a C++20 feature, but
|
||||||
// almost all tested C++17 compilers support this feature already.
|
// almost all tested C++17 compilers support this feature already.
|
||||||
|
// This highly correlates with the preconditions for PYBIND11_DETAIL_DESCR_SRC_LOC_ON.
|
||||||
#if !defined(PYBIND11_TYPE_CASTER_ODR_GUARD_ON) && !defined(PYBIND11_TYPE_CASTER_ODR_GUARD_OFF) \
|
#if !defined(PYBIND11_TYPE_CASTER_ODR_GUARD_ON) && !defined(PYBIND11_TYPE_CASTER_ODR_GUARD_OFF) \
|
||||||
&& !defined(__INTEL_COMPILER) \
|
&& defined(PYBIND11_DETAIL_DESCR_SRC_LOC_ON)
|
||||||
&& ((defined(_MSC_VER) && _MSC_VER >= 1920) || defined(PYBIND11_CPP17))
|
|
||||||
# define PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
# define PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
||||||
#endif
|
#endif
|
||||||
// To explain the above:
|
|
||||||
// * MSVC 2017 does not support __builtin_FILE(), __builtin_LINE().
|
|
||||||
// * Intel 2021.6.0.20220226 (g++ 9.4 mode) __builtin_LINE() is unreliable
|
|
||||||
// (line numbers vary between translation units).
|
|
||||||
|
|
||||||
#ifndef PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
#ifndef PYBIND11_TYPE_CASTER_ODR_GUARD_ON
|
||||||
|
|
||||||
@ -31,7 +29,6 @@
|
|||||||
|
|
||||||
# include "../pytypes.h"
|
# include "../pytypes.h"
|
||||||
# include "common.h"
|
# include "common.h"
|
||||||
# include "descr.h"
|
|
||||||
# include "typeid.h"
|
# include "typeid.h"
|
||||||
|
|
||||||
# include <cstdio>
|
# include <cstdio>
|
||||||
@ -46,19 +43,6 @@
|
|||||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
struct src_loc {
|
|
||||||
const char *file;
|
|
||||||
unsigned line;
|
|
||||||
|
|
||||||
// constexpr src_loc() : file(nullptr), line(0) {}
|
|
||||||
constexpr src_loc(const char *file, unsigned line) : file(file), line(line) {}
|
|
||||||
|
|
||||||
static constexpr src_loc here(const char *file = __builtin_FILE(),
|
|
||||||
unsigned line = __builtin_LINE()) {
|
|
||||||
return src_loc(file, line);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline std::unordered_map<std::type_index, std::string> &type_caster_odr_guard_registry() {
|
inline std::unordered_map<std::type_index, std::string> &type_caster_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;
|
||||||
|
Loading…
Reference in New Issue
Block a user