type_id.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 213 行

CPP
213
字号
// Copyright David Abrahams 2001.// Distributed under the Boost Software License, Version 1.0. (See// accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)#include <boost/python/type_id.hpp>#include <boost/python/detail/decorated_type_id.hpp>#include <utility>#include <vector>#include <algorithm>#include <memory>#include <cstdlib>#include <cstring>#if defined(__QNXNTO__)# include <ostream>#else                       /*  defined(__QNXNTO__) */#if !defined(__GNUC__) || __GNUC__ >= 3 || __SGI_STL_PORT || __EDG_VERSION__# include <ostream>#else # include <ostream.h>#endif #  ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE#   if defined(__GNUC__) &&  __GNUC__ >= 3// http://lists.debian.org/debian-gcc/2003/09/msg00055.html notes// that, in cxxabi.h of gcc-3.x for x < 4, this type is used before it// is declared.#    if __GNUC__ == 3 && __GNUC_MINOR__ < 4class __class_type_info;#    endif#    include <cxxabi.h>#   endif#  endif #endif                      /*  defined(__QNXNTO__) */namespace boost { namespace python {#  ifdef BOOST_PYTHON_HAVE_GCC_CP_DEMANGLE#   if defined(__QNXNTO__)namespace cxxabi {extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);}#   else                    /*  defined(__QNXNTO__) */#    ifdef __GNUC__#     if __GNUC__ < 3namespace cxxabi = :: ;extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);#     elsenamespace cxxabi = ::abi;       // GCC 3.1 and later#      if __GNUC__ == 3 && __GNUC_MINOR__ == 0namespace abi{  extern "C" char* __cxa_demangle(char const*, char*, std::size_t*, int*);}#      endif            /*  __GNUC__ == 3 && __GNUC_MINOR__ == 0    */#     endif             /*  __GNUC__ < 3                            */#    endif              /*  __GNUC__                                */#   endif               /*  defined(__QNXNTO__)                     */namespace{  struct compare_first_cstring  {      template <class T>      bool operator()(T const& x, T const& y)      {          return std::strcmp(x.first,y.first) < 0;      }  };    struct free_mem  {      free_mem(char*p)          : p(p) {}          ~free_mem()      {          std::free(p);      }      char* p;  };}bool cxxabi_cxa_demangle_is_broken(){    static bool was_tested = false;    static bool is_broken = false;    if (!was_tested) {        int status;        free_mem keeper(cxxabi::__cxa_demangle("b", 0, 0, &status));        was_tested = true;        if (status == -2 || strcmp(keeper.p, "bool") != 0) {          is_broken = true;        }    }    return is_broken;}namespace detail{  BOOST_PYTHON_DECL char const* gcc_demangle(char const* mangled)  {      typedef std::vector<          std::pair<char const*, char const*>      > mangling_map;            static mangling_map demangler;      mangling_map::iterator p          = std::lower_bound(              demangler.begin(), demangler.end()            , std::make_pair(mangled, (char const*)0)            , compare_first_cstring());            if (p == demangler.end() || strcmp(p->first, mangled))      {          int status;          free_mem keeper(              cxxabi::__cxa_demangle(mangled, 0, 0, &status)              );              assert(status != -3); // invalid argument error              if (status == -1)          {              throw std::bad_alloc();          }          else          {              char const* demangled                = status == -2                  // Invalid mangled name.  Best we can do is to                  // return it intact.                  ? mangled                  : keeper.p;              // Ult Mundane, 2005 Aug 17              // Contributed under the Boost Software License, Version 1.0.              // (See accompanying file LICENSE_1_0.txt or copy at              // http://www.boost.org/LICENSE_1_0.txt)              // The __cxa_demangle function is supposed to translate              // builtin types from their one-character mangled names,              // but it doesn't in gcc 3.3.5 and gcc 3.4.x.              if (cxxabi_cxa_demangle_is_broken()                  && status == -2 && strlen(mangled) == 1)              {                  // list from                  // http://www.codesourcery.com/cxx-abi/abi.html                  switch (mangled[0])                  {                      case 'v': demangled = "void"; break;                      case 'w': demangled = "wchar_t"; break;                      case 'b': demangled = "bool"; break;                      case 'c': demangled = "char"; break;                      case 'a': demangled = "signed char"; break;                      case 'h': demangled = "unsigned char"; break;                      case 's': demangled = "short"; break;                      case 't': demangled = "unsigned short"; break;                      case 'i': demangled = "int"; break;                      case 'j': demangled = "unsigned int"; break;                      case 'l': demangled = "long"; break;                      case 'm': demangled = "unsigned long"; break;                      case 'x': demangled = "long long"; break;                      case 'y': demangled = "unsigned long long"; break;                      case 'n': demangled = "__int128"; break;                      case 'o': demangled = "unsigned __int128"; break;                      case 'f': demangled = "float"; break;                      case 'd': demangled = "double"; break;                      case 'e': demangled = "long double"; break;                      case 'g': demangled = "__float128"; break;                      case 'z': demangled = "..."; break;                  }              }              p = demangler.insert(p, std::make_pair(mangled, demangled));              keeper.p = 0;          }      }            return p->second;  }}#  endifBOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, type_info const& x){    return os << x.name();}namespace detail{  BOOST_PYTHON_DECL std::ostream& operator<<(std::ostream& os, detail::decorated_type_info const& x)  {      os << x.m_base_type;      if (x.m_decoration & decorated_type_info::const_)          os << " const";      if (x.m_decoration & decorated_type_info::volatile_)          os << " volatile";      if (x.m_decoration & decorated_type_info::reference)          os << "&";      return os;  }}}} // namespace boost::python::converter

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?