/* pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time Copyright (c) 2016 Wenzel Jakob 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" NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 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 struct descr { char text[N + 1]; constexpr descr() : text{'\0'} { } constexpr descr(char const (&s)[N+1]) : descr(s, make_index_sequence()) { } template constexpr descr(char const (&s)[N+1], index_sequence) : text{s[Is]..., '\0'} { } template constexpr descr(char c, Chars... cs) : text{c, static_cast(cs)..., '\0'} { } static constexpr std::array types() { return {{&typeid(Ts)..., nullptr}}; } }; template constexpr descr plus_impl(const descr &a, const descr &b, index_sequence, index_sequence) { return {a.text[Is1]..., b.text[Is2]...}; } template constexpr descr operator+(const descr &a, const descr &b) { return plus_impl(a, b, make_index_sequence(), make_index_sequence()); } template constexpr descr _(char const(&text)[N]) { return descr(text); } constexpr descr<0> _(char const(&)[1]) { return {}; } template struct int_to_str : int_to_str { }; template struct int_to_str<0, Digits...> { static constexpr auto digits = descr(('0' + Digits)...); }; // Ternary description (like std::conditional) template constexpr enable_if_t> _(char const(&text1)[N1], char const(&)[N2]) { return _(text1); } template constexpr enable_if_t> _(char const(&)[N1], char const(&text2)[N2]) { return _(text2); } template constexpr enable_if_t _(const T1 &d, const T2 &) { return d; } template constexpr enable_if_t _(const T1 &, const T2 &d) { return d; } template auto constexpr _() -> decltype(int_to_str::digits) { return int_to_str::digits; } template constexpr descr<1, Type> _() { return {'%'}; } constexpr descr<0> concat() { return {}; } template constexpr descr concat(const descr &descr) { return descr; } template constexpr auto concat(const descr &d, const Args &...args) -> decltype(std::declval>() + concat(args...)) { return d + _(", ") + concat(args...); } template constexpr descr type_descr(const descr &descr) { return _("{") + descr + _("}"); } NAMESPACE_END(detail) NAMESPACE_END(PYBIND11_NAMESPACE)