125 lines
4.6 KiB
C++
125 lines
4.6 KiB
C++
/*
|
|
* 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 <danny@nerdcruft.net>
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "../algo/search.hpp"
|
|
#include "../std.hpp"
|
|
|
|
#include <string_view>
|
|
#include <algorithm>
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
namespace cruft::introspection::name {
|
|
template <typename T>
|
|
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<int, std::__1::allocator<int> >]
|
|
|
|
std::string_view const prefix = "[T = ";
|
|
#elif defined(__GNUC__)
|
|
// PRETTY_FUNCTION = "constexpr std::string_view cruft::type_name() [with T = std::__debug::vector<int>; std::string_view = std::basic_string_view<char>]"
|
|
|
|
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 <typename T>
|
|
constexpr
|
|
std::string_view bare (void)
|
|
{
|
|
|
|
auto const fullname = full<T> ();
|
|
|
|
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<i08> (void) { return "i08"; }
|
|
template <> constexpr std::string_view bare<i16> (void) { return "i16"; }
|
|
template <> constexpr std::string_view bare<i32> (void) { return "i32"; }
|
|
template <> constexpr std::string_view bare<i64> (void) { return "i64"; }
|
|
|
|
template <> constexpr std::string_view bare<u08> (void) { return "u08"; }
|
|
template <> constexpr std::string_view bare<u16> (void) { return "u16"; }
|
|
template <> constexpr std::string_view bare<u32> (void) { return "u32"; }
|
|
template <> constexpr std::string_view bare<u64> (void) { return "u64"; }
|
|
|
|
template <> constexpr std::string_view bare<f32> (void) { return "f32"; }
|
|
template <> constexpr std::string_view bare<f64> (void) { return "f64"; }
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
template <typename T>
|
|
struct type_char;
|
|
|
|
template <> struct type_char<float > { static constexpr char value = 'f'; };
|
|
template <> struct type_char<double> { 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<uint16_t> { static constexpr char value = 'u'; };
|
|
template <> struct type_char<uint32_t> { static constexpr char value = 'u'; };
|
|
template <> struct type_char<uint64_t> { static constexpr char value = 'u'; };
|
|
|
|
template <typename T>
|
|
constexpr auto type_char_v = type_char<T>::value;
|
|
}
|