mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 22:52:01 +00:00
f33f6afb66
* chore(deps): update pre-commit hooks updates: - [github.com/pre-commit/mirrors-clang-format: v17.0.6 → v18.1.2](https://github.com/pre-commit/mirrors-clang-format/compare/v17.0.6...v18.1.2) - [github.com/astral-sh/ruff-pre-commit: v0.2.0 → v0.3.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.2.0...v0.3.5) - [github.com/pre-commit/mirrors-mypy: v1.8.0 → v1.9.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.8.0...v1.9.0) - [github.com/Lucas-C/pre-commit-hooks: v1.5.4 → v1.5.5](https://github.com/Lucas-C/pre-commit-hooks/compare/v1.5.4...v1.5.5) - [github.com/sirosen/texthooks: 0.6.4 → 0.6.6](https://github.com/sirosen/texthooks/compare/0.6.4...0.6.6) - [github.com/shellcheck-py/shellcheck-py: v0.9.0.6 → v0.10.0.1](https://github.com/shellcheck-py/shellcheck-py/compare/v0.9.0.6...v0.10.0.1) - [github.com/PyCQA/pylint: v3.0.3 → v3.1.0](https://github.com/PyCQA/pylint/compare/v3.0.3...v3.1.0) - [github.com/python-jsonschema/check-jsonschema: 0.28.0 → 0.28.1](https://github.com/python-jsonschema/check-jsonschema/compare/0.28.0...0.28.1) * style: pre-commit fixes * fix(types): correction for better typing Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> --------- Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
173 lines
5.9 KiB
C++
173 lines
5.9 KiB
C++
/*
|
|
pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time
|
|
|
|
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
|
|
|
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
|
|
|
|
#include "common.h"
|
|
|
|
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
|
PYBIND11_NAMESPACE_BEGIN(detail)
|
|
|
|
#if !defined(_MSC_VER)
|
|
# define PYBIND11_DESCR_CONSTEXPR static constexpr
|
|
#else
|
|
# define PYBIND11_DESCR_CONSTEXPR const
|
|
#endif
|
|
|
|
/* Concatenate type signatures at compile time */
|
|
template <size_t N, typename... Ts>
|
|
struct descr {
|
|
char text[N + 1]{'\0'};
|
|
|
|
constexpr descr() = default;
|
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
constexpr descr(char const (&s)[N + 1]) : descr(s, make_index_sequence<N>()) {}
|
|
|
|
template <size_t... Is>
|
|
constexpr descr(char const (&s)[N + 1], index_sequence<Is...>) : text{s[Is]..., '\0'} {}
|
|
|
|
template <typename... Chars>
|
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
constexpr descr(char c, Chars... cs) : text{c, static_cast<char>(cs)..., '\0'} {}
|
|
|
|
static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() {
|
|
return {{&typeid(Ts)..., nullptr}};
|
|
}
|
|
};
|
|
|
|
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2, size_t... Is1, size_t... Is2>
|
|
constexpr descr<N1 + N2, Ts1..., Ts2...> plus_impl(const descr<N1, Ts1...> &a,
|
|
const descr<N2, Ts2...> &b,
|
|
index_sequence<Is1...>,
|
|
index_sequence<Is2...>) {
|
|
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(b);
|
|
return {a.text[Is1]..., b.text[Is2]...};
|
|
}
|
|
|
|
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
|
|
constexpr descr<N1 + N2, Ts1..., Ts2...> operator+(const descr<N1, Ts1...> &a,
|
|
const descr<N2, Ts2...> &b) {
|
|
return plus_impl(a, b, make_index_sequence<N1>(), make_index_sequence<N2>());
|
|
}
|
|
|
|
template <size_t N>
|
|
constexpr descr<N - 1> const_name(char const (&text)[N]) {
|
|
return descr<N - 1>(text);
|
|
}
|
|
constexpr descr<0> const_name(char const (&)[1]) { return {}; }
|
|
|
|
template <size_t Rem, size_t... Digits>
|
|
struct int_to_str : int_to_str<Rem / 10, Rem % 10, Digits...> {};
|
|
template <size_t... Digits>
|
|
struct int_to_str<0, Digits...> {
|
|
// WARNING: This only works with C++17 or higher.
|
|
static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...);
|
|
};
|
|
|
|
// Ternary description (like std::conditional)
|
|
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]) {
|
|
return const_name(text1);
|
|
}
|
|
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]) {
|
|
return const_name(text2);
|
|
}
|
|
|
|
template <bool B, typename T1, typename T2>
|
|
constexpr enable_if_t<B, T1> const_name(const T1 &d, const T2 &) {
|
|
return d;
|
|
}
|
|
template <bool B, typename T1, typename T2>
|
|
constexpr enable_if_t<!B, T2> const_name(const T1 &, const T2 &d) {
|
|
return d;
|
|
}
|
|
|
|
template <size_t Size>
|
|
auto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
|
|
return int_to_str<Size / 10, Size % 10>::digits;
|
|
}
|
|
|
|
template <typename Type>
|
|
constexpr descr<1, Type> const_name() {
|
|
return {'%'};
|
|
}
|
|
|
|
// If "_" is defined as a macro, py::detail::_ cannot be provided.
|
|
// It is therefore best to use py::detail::const_name universally.
|
|
// This block is for backward compatibility only.
|
|
// (The const_name code is repeated to avoid introducing a "_" #define ourselves.)
|
|
#ifndef _
|
|
# define PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
|
|
template <size_t N>
|
|
constexpr descr<N - 1> _(char const (&text)[N]) {
|
|
return const_name<N>(text);
|
|
}
|
|
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]) {
|
|
return const_name<B, N1, N2>(text1, text2);
|
|
}
|
|
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]) {
|
|
return const_name<B, N1, N2>(text1, text2);
|
|
}
|
|
template <bool B, typename T1, typename T2>
|
|
constexpr enable_if_t<B, T1> _(const T1 &d1, const T2 &d2) {
|
|
return const_name<B, T1, T2>(d1, d2);
|
|
}
|
|
template <bool B, typename T1, typename T2>
|
|
constexpr enable_if_t<!B, T2> _(const T1 &d1, const T2 &d2) {
|
|
return const_name<B, T1, T2>(d1, d2);
|
|
}
|
|
|
|
template <size_t Size>
|
|
auto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
|
|
return const_name<Size>();
|
|
}
|
|
template <typename Type>
|
|
constexpr descr<1, Type> _() {
|
|
return const_name<Type>();
|
|
}
|
|
#endif // #ifndef _
|
|
|
|
constexpr descr<0> concat() { return {}; }
|
|
|
|
template <size_t N, typename... Ts>
|
|
constexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {
|
|
return descr;
|
|
}
|
|
|
|
#ifdef __cpp_fold_expressions
|
|
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
|
|
constexpr descr<N1 + N2 + 2, Ts1..., Ts2...> operator,(const descr<N1, Ts1...> &a,
|
|
const descr<N2, Ts2...> &b) {
|
|
return a + const_name(", ") + b;
|
|
}
|
|
|
|
template <size_t N, typename... Ts, typename... Args>
|
|
constexpr auto concat(const descr<N, Ts...> &d, const Args &...args) {
|
|
return (d, ..., args);
|
|
}
|
|
#else
|
|
template <size_t N, typename... Ts, typename... Args>
|
|
constexpr auto concat(const descr<N, Ts...> &d,
|
|
const Args &...args) -> decltype(std::declval<descr<N + 2, Ts...>>()
|
|
+ concat(args...)) {
|
|
return d + const_name(", ") + concat(args...);
|
|
}
|
|
#endif
|
|
|
|
template <size_t N, typename... Ts>
|
|
constexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {
|
|
return const_name("{") + descr + const_name("}");
|
|
}
|
|
|
|
PYBIND11_NAMESPACE_END(detail)
|
|
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|