1 | /* |
2 | pybind11/detail/typeid.h: Compiler-independent access to type identifiers |
3 | |
4 | Copyright (c) 2016 Wenzel Jakob <[email protected]> |
5 | |
6 | All rights reserved. Use of this source code is governed by a |
7 | BSD-style license that can be found in the LICENSE file. |
8 | */ |
9 | |
10 | #pragma once |
11 | |
12 | #include <cstdio> |
13 | #include <cstdlib> |
14 | |
15 | #if defined(__GNUG__) |
16 | # include <cxxabi.h> |
17 | #endif |
18 | |
19 | #include "common.h" |
20 | |
21 | PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) |
22 | PYBIND11_NAMESPACE_BEGIN(detail) |
23 | |
24 | /// Erase all occurrences of a substring |
25 | inline void erase_all(std::string &string, const std::string &search) { |
26 | for (size_t pos = 0;;) { |
27 | pos = string.find(search, pos); |
28 | if (pos == std::string::npos) { |
29 | break; |
30 | } |
31 | string.erase(pos, search.length()); |
32 | } |
33 | } |
34 | |
35 | PYBIND11_NOINLINE void clean_type_id(std::string &name) { |
36 | #if defined(__GNUG__) |
37 | int status = 0; |
38 | std::unique_ptr<char, void (*)(void *)> res{ |
39 | abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free}; |
40 | if (status == 0) { |
41 | name = res.get(); |
42 | } |
43 | #else |
44 | detail::erase_all(name, "class " ); |
45 | detail::erase_all(name, "struct " ); |
46 | detail::erase_all(name, "enum " ); |
47 | #endif |
48 | detail::erase_all(name, "pybind11::" ); |
49 | } |
50 | |
51 | inline std::string clean_type_id(const char *typeid_name) { |
52 | std::string name(typeid_name); |
53 | detail::clean_type_id(name); |
54 | return name; |
55 | } |
56 | |
57 | PYBIND11_NAMESPACE_END(detail) |
58 | |
59 | /// Return a string representation of a C++ type |
60 | template <typename T> |
61 | static std::string type_id() { |
62 | return detail::clean_type_id(typeid(T).name()); |
63 | } |
64 | |
65 | PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) |
66 | |