/* * Copyright (c) Facebook, Inc. and its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include namespace folly { namespace detail { template struct pretty_carray { char data[S]; }; template static constexpr pretty_carray pretty_carray_from(char const (&in)[S]) { pretty_carray out{}; for (std::size_t i = 0; i < S; ++i) { out.data[i] = in[i]; } return out; } struct pretty_info { std::size_t b; std::size_t e; }; template static constexpr To pretty_info_to(pretty_info info, char const (&name)[S]) { return To(name + info.b, info.e - info.b); } template static constexpr std::size_t pretty_lfind( char const (&haystack)[S], char const needle) { for (std::size_t i = 0; i < S - 1; ++i) { if (haystack[i] == needle) { return i; } } return ~std::size_t(0); } template static constexpr std::size_t pretty_rfind( char const (&haystack)[S], char const needle) { for (std::size_t i = S; i != 0; --i) { if (haystack[i - 1] == needle) { return i - 1; } } return ~std::size_t(0); } struct pretty_tag_msc {}; struct pretty_tag_gcc {}; using pretty_default_tag = std::conditional_t< // kMscVer && !kIsClang, pretty_tag_msc, pretty_tag_gcc>; template static constexpr auto pretty_raw(pretty_tag_msc) { #if defined(_MSC_VER) return pretty_carray_from(__FUNCSIG__); #endif } template static constexpr auto pretty_raw(pretty_tag_gcc) { #if defined(__GNUC__) || defined(__clang__) return pretty_carray_from(__PRETTY_FUNCTION__); #endif } template static constexpr pretty_info pretty_parse( pretty_tag_msc, char const (&name)[S]) { // void __cdecl folly::detail::pretty_raw<{...}>( // folly::detail::pretty_tag_msc) auto const la = pretty_lfind(name, '<'); auto const rp = pretty_rfind(name, '>'); return pretty_info{la + 1, rp}; } template static constexpr pretty_info pretty_parse( pretty_tag_gcc, char const (&name)[S]) { // void folly::detail::pretty_raw( // folly::detail::pretty_tag_gcc) [T = {...}] auto const eq = pretty_lfind(name, '='); auto const br = pretty_rfind(name, ']'); return pretty_info{eq + 2, br}; } template struct pretty_name_zarray { static constexpr auto raw_() { constexpr auto const raw_ = pretty_raw(Tag{}); return raw_; } static constexpr auto raw = raw_(); // indirection b/c of gcc-5.3 ice, gh#1105 static constexpr auto info = pretty_parse(Tag{}, raw.data); static constexpr auto size = info.e - info.b; static constexpr auto zarray_() { pretty_carray data{}; for (std::size_t i = 0; i < size; ++i) { data.data[i] = raw.data[info.b + i]; } data.data[size] = 0; return data; } static constexpr pretty_carray zarray = zarray_(); }; template constexpr pretty_carray::size + 1> pretty_name_zarray::zarray; } // namespace detail // pretty_name // // Returns a statically-allocated C string containing the pretty name of T. // // The pretty name of a type varies by compiler, may include tokens which // would not be present in the type name as it is spelled in the source code // or as it would be symbolized, and may not include tokens which would be // present in the type name as it would be symbolized. template constexpr char const* pretty_name() { return detail::pretty_name_zarray::zarray.data; } } // namespace folly