112391Sjason@lowepower.com/* 214299Sbbruce@ucdavis.edu pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time 312391Sjason@lowepower.com 412391Sjason@lowepower.com Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch> 512391Sjason@lowepower.com 612391Sjason@lowepower.com All rights reserved. Use of this source code is governed by a 712391Sjason@lowepower.com BSD-style license that can be found in the LICENSE file. 812391Sjason@lowepower.com*/ 912391Sjason@lowepower.com 1012391Sjason@lowepower.com#pragma once 1112391Sjason@lowepower.com 1212391Sjason@lowepower.com#include "common.h" 1312391Sjason@lowepower.com 1412391Sjason@lowepower.comNAMESPACE_BEGIN(PYBIND11_NAMESPACE) 1512391Sjason@lowepower.comNAMESPACE_BEGIN(detail) 1612391Sjason@lowepower.com 1714299Sbbruce@ucdavis.edu#if !defined(_MSC_VER) 1814299Sbbruce@ucdavis.edu# define PYBIND11_DESCR_CONSTEXPR static constexpr 1914299Sbbruce@ucdavis.edu#else 2014299Sbbruce@ucdavis.edu# define PYBIND11_DESCR_CONSTEXPR const 2114299Sbbruce@ucdavis.edu#endif 2212391Sjason@lowepower.com 2314299Sbbruce@ucdavis.edu/* Concatenate type signatures at compile time */ 2414299Sbbruce@ucdavis.edutemplate <size_t N, typename... Ts> 2514299Sbbruce@ucdavis.edustruct descr { 2614299Sbbruce@ucdavis.edu char text[N + 1]; 2712391Sjason@lowepower.com 2814299Sbbruce@ucdavis.edu constexpr descr() : text{'\0'} { } 2914299Sbbruce@ucdavis.edu constexpr descr(char const (&s)[N+1]) : descr(s, make_index_sequence<N>()) { } 3012391Sjason@lowepower.com 3114299Sbbruce@ucdavis.edu template <size_t... Is> 3214299Sbbruce@ucdavis.edu constexpr descr(char const (&s)[N+1], index_sequence<Is...>) : text{s[Is]..., '\0'} { } 3314299Sbbruce@ucdavis.edu 3414299Sbbruce@ucdavis.edu template <typename... Chars> 3514299Sbbruce@ucdavis.edu constexpr descr(char c, Chars... cs) : text{c, static_cast<char>(cs)..., '\0'} { } 3614299Sbbruce@ucdavis.edu 3714299Sbbruce@ucdavis.edu static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() { 3814299Sbbruce@ucdavis.edu return {{&typeid(Ts)..., nullptr}}; 3912391Sjason@lowepower.com } 4012391Sjason@lowepower.com}; 4112391Sjason@lowepower.com 4214299Sbbruce@ucdavis.edutemplate <size_t N1, size_t N2, typename... Ts1, typename... Ts2, size_t... Is1, size_t... Is2> 4314299Sbbruce@ucdavis.educonstexpr descr<N1 + N2, Ts1..., Ts2...> plus_impl(const descr<N1, Ts1...> &a, const descr<N2, Ts2...> &b, 4414299Sbbruce@ucdavis.edu index_sequence<Is1...>, index_sequence<Is2...>) { 4514299Sbbruce@ucdavis.edu return {a.text[Is1]..., b.text[Is2]...}; 4612391Sjason@lowepower.com} 4712391Sjason@lowepower.com 4814299Sbbruce@ucdavis.edutemplate <size_t N1, size_t N2, typename... Ts1, typename... Ts2> 4914299Sbbruce@ucdavis.educonstexpr descr<N1 + N2, Ts1..., Ts2...> operator+(const descr<N1, Ts1...> &a, const descr<N2, Ts2...> &b) { 5014299Sbbruce@ucdavis.edu return plus_impl(a, b, make_index_sequence<N1>(), make_index_sequence<N2>()); 5114299Sbbruce@ucdavis.edu} 5214299Sbbruce@ucdavis.edu 5314299Sbbruce@ucdavis.edutemplate <size_t N> 5414299Sbbruce@ucdavis.educonstexpr descr<N - 1> _(char const(&text)[N]) { return descr<N - 1>(text); } 5514299Sbbruce@ucdavis.educonstexpr descr<0> _(char const(&)[1]) { return {}; } 5614299Sbbruce@ucdavis.edu 5712391Sjason@lowepower.comtemplate <size_t Rem, size_t... Digits> struct int_to_str : int_to_str<Rem/10, Rem%10, Digits...> { }; 5812391Sjason@lowepower.comtemplate <size_t...Digits> struct int_to_str<0, Digits...> { 5914299Sbbruce@ucdavis.edu static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...); 6012391Sjason@lowepower.com}; 6112391Sjason@lowepower.com 6212391Sjason@lowepower.com// Ternary description (like std::conditional) 6314299Sbbruce@ucdavis.edutemplate <bool B, size_t N1, size_t N2> 6414299Sbbruce@ucdavis.educonstexpr enable_if_t<B, descr<N1 - 1>> _(char const(&text1)[N1], char const(&)[N2]) { 6512391Sjason@lowepower.com return _(text1); 6612391Sjason@lowepower.com} 6714299Sbbruce@ucdavis.edutemplate <bool B, size_t N1, size_t N2> 6814299Sbbruce@ucdavis.educonstexpr enable_if_t<!B, descr<N2 - 1>> _(char const(&)[N1], char const(&text2)[N2]) { 6912391Sjason@lowepower.com return _(text2); 7012391Sjason@lowepower.com} 7114299Sbbruce@ucdavis.edu 7214299Sbbruce@ucdavis.edutemplate <bool B, typename T1, typename T2> 7314299Sbbruce@ucdavis.educonstexpr enable_if_t<B, T1> _(const T1 &d, const T2 &) { return d; } 7414299Sbbruce@ucdavis.edutemplate <bool B, typename T1, typename T2> 7514299Sbbruce@ucdavis.educonstexpr enable_if_t<!B, T2> _(const T1 &, const T2 &d) { return d; } 7612391Sjason@lowepower.com 7712391Sjason@lowepower.comtemplate <size_t Size> auto constexpr _() -> decltype(int_to_str<Size / 10, Size % 10>::digits) { 7812391Sjason@lowepower.com return int_to_str<Size / 10, Size % 10>::digits; 7912391Sjason@lowepower.com} 8012391Sjason@lowepower.com 8114299Sbbruce@ucdavis.edutemplate <typename Type> constexpr descr<1, Type> _() { return {'%'}; } 8214299Sbbruce@ucdavis.edu 8314299Sbbruce@ucdavis.educonstexpr descr<0> concat() { return {}; } 8414299Sbbruce@ucdavis.edu 8514299Sbbruce@ucdavis.edutemplate <size_t N, typename... Ts> 8614299Sbbruce@ucdavis.educonstexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) { return descr; } 8714299Sbbruce@ucdavis.edu 8814299Sbbruce@ucdavis.edutemplate <size_t N, typename... Ts, typename... Args> 8914299Sbbruce@ucdavis.educonstexpr auto concat(const descr<N, Ts...> &d, const Args &...args) 9014299Sbbruce@ucdavis.edu -> decltype(std::declval<descr<N + 2, Ts...>>() + concat(args...)) { 9114299Sbbruce@ucdavis.edu return d + _(", ") + concat(args...); 9212391Sjason@lowepower.com} 9312391Sjason@lowepower.com 9414299Sbbruce@ucdavis.edutemplate <size_t N, typename... Ts> 9514299Sbbruce@ucdavis.educonstexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) { 9614299Sbbruce@ucdavis.edu return _("{") + descr + _("}"); 9712391Sjason@lowepower.com} 9812391Sjason@lowepower.com 9912391Sjason@lowepower.comNAMESPACE_END(detail) 10012391Sjason@lowepower.comNAMESPACE_END(PYBIND11_NAMESPACE) 101