112391Sjason@lowepower.com/*
212391Sjason@lowepower.com    pybind11/detail/typeid.h: Compiler-independent access to type identifiers
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 <cstdio>
1312391Sjason@lowepower.com#include <cstdlib>
1412391Sjason@lowepower.com
1512391Sjason@lowepower.com#if defined(__GNUG__)
1612391Sjason@lowepower.com#include <cxxabi.h>
1712391Sjason@lowepower.com#endif
1812391Sjason@lowepower.com
1914299Sbbruce@ucdavis.edu#include "common.h"
2014299Sbbruce@ucdavis.edu
2112391Sjason@lowepower.comNAMESPACE_BEGIN(PYBIND11_NAMESPACE)
2212391Sjason@lowepower.comNAMESPACE_BEGIN(detail)
2312391Sjason@lowepower.com/// Erase all occurrences of a substring
2412391Sjason@lowepower.cominline void erase_all(std::string &string, const std::string &search) {
2512391Sjason@lowepower.com    for (size_t pos = 0;;) {
2612391Sjason@lowepower.com        pos = string.find(search, pos);
2712391Sjason@lowepower.com        if (pos == std::string::npos) break;
2812391Sjason@lowepower.com        string.erase(pos, search.length());
2912391Sjason@lowepower.com    }
3012391Sjason@lowepower.com}
3112391Sjason@lowepower.com
3212391Sjason@lowepower.comPYBIND11_NOINLINE inline void clean_type_id(std::string &name) {
3312391Sjason@lowepower.com#if defined(__GNUG__)
3412391Sjason@lowepower.com    int status = 0;
3512391Sjason@lowepower.com    std::unique_ptr<char, void (*)(void *)> res {
3612391Sjason@lowepower.com        abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free };
3712391Sjason@lowepower.com    if (status == 0)
3812391Sjason@lowepower.com        name = res.get();
3912391Sjason@lowepower.com#else
4012391Sjason@lowepower.com    detail::erase_all(name, "class ");
4112391Sjason@lowepower.com    detail::erase_all(name, "struct ");
4212391Sjason@lowepower.com    detail::erase_all(name, "enum ");
4312391Sjason@lowepower.com#endif
4412391Sjason@lowepower.com    detail::erase_all(name, "pybind11::");
4512391Sjason@lowepower.com}
4612391Sjason@lowepower.comNAMESPACE_END(detail)
4712391Sjason@lowepower.com
4812391Sjason@lowepower.com/// Return a string representation of a C++ type
4912391Sjason@lowepower.comtemplate <typename T> static std::string type_id() {
5012391Sjason@lowepower.com    std::string name(typeid(T).name());
5112391Sjason@lowepower.com    detail::clean_type_id(name);
5212391Sjason@lowepower.com    return name;
5312391Sjason@lowepower.com}
5412391Sjason@lowepower.com
5512391Sjason@lowepower.comNAMESPACE_END(PYBIND11_NAMESPACE)
56