Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-17 09:23:48

0001 /*
0002     pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time
0003 
0004     Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
0005 
0006     All rights reserved. Use of this source code is governed by a
0007     BSD-style license that can be found in the LICENSE file.
0008 */
0009 
0010 #pragma once
0011 
0012 #include "common.h"
0013 
0014 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0015 PYBIND11_NAMESPACE_BEGIN(detail)
0016 
0017 #if !defined(_MSC_VER)
0018 #    define PYBIND11_DESCR_CONSTEXPR static constexpr
0019 #else
0020 #    define PYBIND11_DESCR_CONSTEXPR const
0021 #endif
0022 
0023 /* Concatenate type signatures at compile time */
0024 template <size_t N, typename... Ts>
0025 struct descr {
0026     char text[N + 1]{'\0'};
0027 
0028     constexpr descr() = default;
0029     // NOLINTNEXTLINE(google-explicit-constructor)
0030     constexpr descr(char const (&s)[N + 1]) : descr(s, make_index_sequence<N>()) {}
0031 
0032     template <size_t... Is>
0033     constexpr descr(char const (&s)[N + 1], index_sequence<Is...>) : text{s[Is]..., '\0'} {}
0034 
0035     template <typename... Chars>
0036     // NOLINTNEXTLINE(google-explicit-constructor)
0037     constexpr descr(char c, Chars... cs) : text{c, static_cast<char>(cs)..., '\0'} {}
0038 
0039     static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() {
0040         return {{&typeid(Ts)..., nullptr}};
0041     }
0042 };
0043 
0044 template <size_t N1, size_t N2, typename... Ts1, typename... Ts2, size_t... Is1, size_t... Is2>
0045 constexpr descr<N1 + N2, Ts1..., Ts2...> plus_impl(const descr<N1, Ts1...> &a,
0046                                                    const descr<N2, Ts2...> &b,
0047                                                    index_sequence<Is1...>,
0048                                                    index_sequence<Is2...>) {
0049     PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(b);
0050     return {a.text[Is1]..., b.text[Is2]...};
0051 }
0052 
0053 template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
0054 constexpr descr<N1 + N2, Ts1..., Ts2...> operator+(const descr<N1, Ts1...> &a,
0055                                                    const descr<N2, Ts2...> &b) {
0056     return plus_impl(a, b, make_index_sequence<N1>(), make_index_sequence<N2>());
0057 }
0058 
0059 template <size_t N>
0060 constexpr descr<N - 1> const_name(char const (&text)[N]) {
0061     return descr<N - 1>(text);
0062 }
0063 constexpr descr<0> const_name(char const (&)[1]) { return {}; }
0064 
0065 template <size_t Rem, size_t... Digits>
0066 struct int_to_str : int_to_str<Rem / 10, Rem % 10, Digits...> {};
0067 template <size_t... Digits>
0068 struct int_to_str<0, Digits...> {
0069     // WARNING: This only works with C++17 or higher.
0070     static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...);
0071 };
0072 
0073 // Ternary description (like std::conditional)
0074 template <bool B, size_t N1, size_t N2>
0075 constexpr enable_if_t<B, descr<N1 - 1>> const_name(char const (&text1)[N1], char const (&)[N2]) {
0076     return const_name(text1);
0077 }
0078 template <bool B, size_t N1, size_t N2>
0079 constexpr enable_if_t<!B, descr<N2 - 1>> const_name(char const (&)[N1], char const (&text2)[N2]) {
0080     return const_name(text2);
0081 }
0082 
0083 template <bool B, typename T1, typename T2>
0084 constexpr enable_if_t<B, T1> const_name(const T1 &d, const T2 &) {
0085     return d;
0086 }
0087 template <bool B, typename T1, typename T2>
0088 constexpr enable_if_t<!B, T2> const_name(const T1 &, const T2 &d) {
0089     return d;
0090 }
0091 
0092 template <size_t Size>
0093 auto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
0094     return int_to_str<Size / 10, Size % 10>::digits;
0095 }
0096 
0097 template <typename Type>
0098 constexpr descr<1, Type> const_name() {
0099     return {'%'};
0100 }
0101 
0102 // Use a different name based on whether the parameter is used as input or output
0103 template <size_t N1, size_t N2>
0104 constexpr descr<N1 + N2 + 1> io_name(char const (&text1)[N1], char const (&text2)[N2]) {
0105     return const_name("@") + const_name(text1) + const_name("@") + const_name(text2)
0106            + const_name("@");
0107 }
0108 
0109 // Ternary description for io_name (like the numeric type_caster)
0110 template <bool B, size_t N1, size_t N2, size_t N3, size_t N4>
0111 constexpr enable_if_t<B, descr<N1 + N2 + 1>>
0112 io_name(char const (&text1)[N1], char const (&text2)[N2], char const (&)[N3], char const (&)[N4]) {
0113     return io_name(text1, text2);
0114 }
0115 
0116 template <bool B, size_t N1, size_t N2, size_t N3, size_t N4>
0117 constexpr enable_if_t<!B, descr<N3 + N4 + 1>>
0118 io_name(char const (&)[N1], char const (&)[N2], char const (&text3)[N3], char const (&text4)[N4]) {
0119     return io_name(text3, text4);
0120 }
0121 
0122 // If "_" is defined as a macro, py::detail::_ cannot be provided.
0123 // It is therefore best to use py::detail::const_name universally.
0124 // This block is for backward compatibility only.
0125 // (The const_name code is repeated to avoid introducing a "_" #define ourselves.)
0126 #ifndef _
0127 #    define PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
0128 template <size_t N>
0129 constexpr descr<N - 1> _(char const (&text)[N]) {
0130     return const_name<N>(text);
0131 }
0132 template <bool B, size_t N1, size_t N2>
0133 constexpr enable_if_t<B, descr<N1 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
0134     return const_name<B, N1, N2>(text1, text2);
0135 }
0136 template <bool B, size_t N1, size_t N2>
0137 constexpr enable_if_t<!B, descr<N2 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
0138     return const_name<B, N1, N2>(text1, text2);
0139 }
0140 template <bool B, typename T1, typename T2>
0141 constexpr enable_if_t<B, T1> _(const T1 &d1, const T2 &d2) {
0142     return const_name<B, T1, T2>(d1, d2);
0143 }
0144 template <bool B, typename T1, typename T2>
0145 constexpr enable_if_t<!B, T2> _(const T1 &d1, const T2 &d2) {
0146     return const_name<B, T1, T2>(d1, d2);
0147 }
0148 
0149 template <size_t Size>
0150 auto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
0151     return const_name<Size>();
0152 }
0153 template <typename Type>
0154 constexpr descr<1, Type> _() {
0155     return const_name<Type>();
0156 }
0157 #endif // #ifndef _
0158 
0159 constexpr descr<0> concat() { return {}; }
0160 constexpr descr<0> union_concat() { return {}; }
0161 
0162 template <size_t N, typename... Ts>
0163 constexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {
0164     return descr;
0165 }
0166 
0167 template <size_t N, typename... Ts>
0168 constexpr descr<N, Ts...> union_concat(const descr<N, Ts...> &descr) {
0169     return descr;
0170 }
0171 
0172 template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
0173 constexpr descr<N1 + N2 + 3, Ts1..., Ts2...> operator|(const descr<N1, Ts1...> &a,
0174                                                        const descr<N2, Ts2...> &b) {
0175     return a + const_name(" | ") + b;
0176 }
0177 
0178 #ifdef __cpp_fold_expressions
0179 template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
0180 constexpr descr<N1 + N2 + 2, Ts1..., Ts2...> operator,(const descr<N1, Ts1...> &a,
0181                                                        const descr<N2, Ts2...> &b) {
0182     return a + const_name(", ") + b;
0183 }
0184 
0185 template <size_t N, typename... Ts, typename... Args>
0186 constexpr auto concat(const descr<N, Ts...> &d, const Args &...args) {
0187     return (d, ..., args);
0188 }
0189 
0190 template <size_t N, typename... Ts, typename... Args>
0191 constexpr auto union_concat(const descr<N, Ts...> &d, const Args &...args) {
0192     return (d | ... | args);
0193 }
0194 
0195 #else
0196 template <size_t N, typename... Ts, typename... Args>
0197 constexpr auto concat(const descr<N, Ts...> &d, const Args &...args)
0198     -> decltype(std::declval<descr<N + 2, Ts...>>() + concat(args...)) {
0199     return d + const_name(", ") + concat(args...);
0200 }
0201 
0202 template <size_t N, typename... Ts, typename... Args>
0203 constexpr auto union_concat(const descr<N, Ts...> &d, const Args &...args)
0204     -> decltype(std::declval<descr<N + 3, Ts...>>() + union_concat(args...)) {
0205     return d + const_name(" | ") + union_concat(args...);
0206 }
0207 
0208 #endif
0209 
0210 template <size_t N, typename... Ts>
0211 constexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {
0212     return const_name("{") + descr + const_name("}");
0213 }
0214 
0215 template <size_t N, typename... Ts>
0216 constexpr descr<N + 4, Ts...> arg_descr(const descr<N, Ts...> &descr) {
0217     return const_name("@^") + descr + const_name("@!");
0218 }
0219 
0220 template <size_t N, typename... Ts>
0221 constexpr descr<N + 4, Ts...> return_descr(const descr<N, Ts...> &descr) {
0222     return const_name("@$") + descr + const_name("@!");
0223 }
0224 
0225 PYBIND11_NAMESPACE_END(detail)
0226 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)