/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2019-2020 Danny Robson */ #pragma once #include "../algo/search.hpp" #include "../std.hpp" #include #include /////////////////////////////////////////////////////////////////////////////// namespace cruft::introspection::name { template constexpr std::string_view full (void) { std::string_view pretty_function (__PRETTY_FUNCTION__); #ifdef __clang__ // PRETTY_FUNCTION = std::string_view cruft::type_name() [T = std::__1::vector >] std::string_view const prefix = "[T = "; #elif defined(__GNUC__) // PRETTY_FUNCTION = "constexpr std::string_view cruft::type_name() [with T = std::__debug::vector; std::string_view = std::basic_string_view]" std::string_view prefix = "[with T = "; #else #error "Unsupported compiler" #endif // Find the location where the type begins. auto const type_begin = std::search ( pretty_function.begin (), pretty_function.end (), prefix.begin (), prefix.end () ) + prefix.size (); // Find the point the type name ends. Both use ']', but gcc lists // std::string_view in the function signature too and so requires the // delimiting ';' as a suffix. char const suffixes[] = ";]"; auto const type_end = std::find_first_of ( type_begin, pretty_function.end (), std::begin (suffixes), std::end (suffixes) ); // Find the start of the first template parameter so we can cut it out. // If this isn't present we end up with a pointer to the end of the // type string which is the end of the type anyway. auto const template_start = std::find (type_begin, type_end, '<'); auto const template_end = cruft::search::balanced (template_start, type_end, '<', '>'); return std::string_view ( type_begin, std::distance (type_begin, template_end) ); } template constexpr std::string_view bare (void) { auto const fullname = full (); constexpr char const namespace_symbol[] = "::"; auto const last_namespace_pos = std::search ( std::rbegin (fullname), std::rend (fullname), namespace_symbol + 0, namespace_symbol + 2 ); auto const length = std::distance (std::rbegin (fullname), last_namespace_pos); auto const offset = fullname.size () - length; return std::string_view (fullname.data () + offset, length); } template <> constexpr std::string_view bare (void) { return "i08"; } template <> constexpr std::string_view bare (void) { return "i16"; } template <> constexpr std::string_view bare (void) { return "i32"; } template <> constexpr std::string_view bare (void) { return "i64"; } template <> constexpr std::string_view bare (void) { return "u08"; } template <> constexpr std::string_view bare (void) { return "u16"; } template <> constexpr std::string_view bare (void) { return "u32"; } template <> constexpr std::string_view bare (void) { return "u64"; } template <> constexpr std::string_view bare (void) { return "f32"; } template <> constexpr std::string_view bare (void) { return "f64"; } /////////////////////////////////////////////////////////////////////////// template struct type_char; template <> struct type_char { static constexpr char value = 'f'; }; template <> struct type_char { static constexpr char value = 'd'; }; template <> struct type_char< int8_t> { static constexpr char value = 'i'; }; template <> struct type_char< int16_t> { static constexpr char value = 'i'; }; template <> struct type_char< int32_t> { static constexpr char value = 'i'; }; template <> struct type_char< int64_t> { static constexpr char value = 'i'; }; template <> struct type_char< uint8_t> { static constexpr char value = 'u'; }; template <> struct type_char { static constexpr char value = 'u'; }; template <> struct type_char { static constexpr char value = 'u'; }; template <> struct type_char { static constexpr char value = 'u'; }; template constexpr auto type_char_v = type_char::value; }