(root)/
gcc-13.2.0/
libstdc++-v3/
include/
debug/
formatter.h
       1  // Debug-mode error formatting implementation -*- C++ -*-
       2  
       3  // Copyright (C) 2003-2023 Free Software Foundation, Inc.
       4  //
       5  // This file is part of the GNU ISO C++ Library.  This library is free
       6  // software; you can redistribute it and/or modify it under the
       7  // terms of the GNU General Public License as published by the
       8  // Free Software Foundation; either version 3, or (at your option)
       9  // any later version.
      10  
      11  // This library is distributed in the hope that it will be useful,
      12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  // GNU General Public License for more details.
      15  
      16  // Under Section 7 of GPL version 3, you are granted additional
      17  // permissions described in the GCC Runtime Library Exception, version
      18  // 3.1, as published by the Free Software Foundation.
      19  
      20  // You should have received a copy of the GNU General Public License and
      21  // a copy of the GCC Runtime Library Exception along with this program;
      22  // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23  // <http://www.gnu.org/licenses/>.
      24  
      25  /** @file debug/formatter.h
      26   *  This file is a GNU debug extension to the Standard C++ Library.
      27   */
      28  
      29  #ifndef _GLIBCXX_DEBUG_FORMATTER_H
      30  #define _GLIBCXX_DEBUG_FORMATTER_H 1
      31  
      32  #include <bits/c++config.h>
      33  
      34  #if _GLIBCXX_HAVE_STACKTRACE
      35  extern "C"
      36  {
      37    struct __glibcxx_backtrace_state*
      38    __glibcxx_backtrace_create_state(const char*, int,
      39  				   void(*)(void*, const char*, int),
      40  				   void*);
      41    int
      42    __glibcxx_backtrace_full(
      43      struct __glibcxx_backtrace_state*, int,
      44      int (*)(void*, __UINTPTR_TYPE__, const char *, int, const char*),
      45      void (*)(void*, const char*, int),
      46      void*);
      47  }
      48  #endif
      49  
      50  #if __cpp_rtti
      51  # include <typeinfo>
      52  # define _GLIBCXX_TYPEID(_Type) &typeid(_Type)
      53  #else
      54  namespace std
      55  {
      56    class type_info;
      57  }
      58  # define _GLIBCXX_TYPEID(_Type) 0
      59  #endif
      60  
      61  #if __cplusplus >= 201103L
      62  namespace __gnu_cxx
      63  {
      64  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      65  
      66  template<typename _Iterator, typename _Container>
      67    class __normal_iterator;
      68  
      69  _GLIBCXX_END_NAMESPACE_VERSION
      70  }
      71  
      72  namespace std
      73  {
      74  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      75  
      76  template<typename _Iterator>
      77    class reverse_iterator;
      78  
      79  template<typename _Iterator>
      80    class move_iterator;
      81  
      82  _GLIBCXX_END_NAMESPACE_VERSION
      83  }
      84  #endif
      85  
      86  namespace __gnu_debug
      87  {
      88    using std::type_info;
      89  
      90    template<typename _Iterator>
      91      _GLIBCXX_CONSTEXPR
      92      bool __check_singular(_Iterator const&);
      93  
      94    class _Safe_sequence_base;
      95  
      96    template<typename _Iterator, typename _Sequence, typename _Category>
      97      class _Safe_iterator;
      98  
      99    template<typename _Iterator, typename _Sequence>
     100      class _Safe_local_iterator;
     101  
     102    template<typename _Sequence>
     103      class _Safe_sequence;
     104  
     105    enum _Debug_msg_id
     106    {
     107      // General checks
     108      __msg_valid_range,
     109      __msg_insert_singular,
     110      __msg_insert_different,
     111      __msg_erase_bad,
     112      __msg_erase_different,
     113      __msg_subscript_oob,
     114      __msg_empty,
     115      __msg_unpartitioned,
     116      __msg_unpartitioned_pred,
     117      __msg_unsorted,
     118      __msg_unsorted_pred,
     119      __msg_not_heap,
     120      __msg_not_heap_pred,
     121      // std::bitset checks
     122      __msg_bad_bitset_write,
     123      __msg_bad_bitset_read,
     124      __msg_bad_bitset_flip,
     125      // std::list checks
     126      __msg_self_splice,
     127      __msg_splice_alloc,
     128      __msg_splice_bad,
     129      __msg_splice_other,
     130      __msg_splice_overlap,
     131      // iterator checks
     132      __msg_init_singular,
     133      __msg_init_copy_singular,
     134      __msg_init_const_singular,
     135      __msg_copy_singular,
     136      __msg_bad_deref,
     137      __msg_bad_inc,
     138      __msg_bad_dec,
     139      __msg_iter_subscript_oob,
     140      __msg_advance_oob,
     141      __msg_retreat_oob,
     142      __msg_iter_compare_bad,
     143      __msg_compare_different,
     144      __msg_iter_order_bad,
     145      __msg_order_different,
     146      __msg_distance_bad,
     147      __msg_distance_different,
     148      // istream_iterator
     149      __msg_deref_istream,
     150      __msg_inc_istream,
     151      // ostream_iterator
     152      __msg_output_ostream,
     153      // istreambuf_iterator
     154      __msg_deref_istreambuf,
     155      __msg_inc_istreambuf,
     156      // forward_list
     157      __msg_insert_after_end,
     158      __msg_erase_after_bad,
     159      __msg_valid_range2,
     160      // unordered container local iterators
     161      __msg_local_iter_compare_bad,
     162      __msg_non_empty_range,
     163      // self move assign (no longer used)
     164      __msg_self_move_assign,
     165      // unordered container buckets
     166      __msg_bucket_index_oob,
     167      __msg_valid_load_factor,
     168      // others
     169      __msg_equal_allocs,
     170      __msg_insert_range_from_self,
     171      __msg_irreflexive_ordering
     172    };
     173  
     174    class _Error_formatter
     175    {
     176      // Tags denoting the type of parameter for construction
     177      struct _Is_iterator { };
     178      struct _Is_iterator_value_type { };
     179      struct _Is_sequence { };
     180      struct _Is_instance { };
     181  
     182    public:
     183      /// Whether an iterator is constant, mutable, or unknown
     184      enum _Constness
     185      {
     186        __unknown_constness,
     187        __const_iterator,
     188        __mutable_iterator,
     189        __last_constness
     190      };
     191  
     192      // The state of the iterator (fine-grained), if we know it.
     193      enum _Iterator_state
     194      {
     195        __unknown_state,
     196        __singular,	// singular, may still be attached to a sequence
     197        __begin,		// dereferenceable, and at the beginning
     198        __middle,		// dereferenceable, not at the beginning
     199        __end,		// past-the-end, may be at beginning if sequence empty
     200        __before_begin,	// before begin
     201        __rbegin,		// dereferenceable, and at the reverse-beginning
     202        __rmiddle,	// reverse-dereferenceable, not at the reverse-beginning
     203        __rend,		// reverse-past-the-end
     204        __singular_value_init,	// singular, value initialized
     205        __last_state
     206      };
     207  
     208      // A parameter that may be referenced by an error message
     209      struct _Parameter
     210      {
     211        enum
     212        {
     213  	__unused_param,
     214  	__iterator,
     215  	__sequence,
     216  	__integer,
     217  	__string,
     218  	__instance,
     219  	__iterator_value_type
     220        } _M_kind;
     221  
     222        struct _Named
     223        {
     224  	const char*		_M_name;
     225        };
     226  
     227        struct _Type : _Named
     228        {
     229  	const type_info*	_M_type;
     230        };
     231  
     232        struct _Instance : _Type
     233        {
     234  	const void*		_M_address;
     235        };
     236  
     237        union
     238        {
     239  	// When _M_kind == __iterator
     240  	struct : _Instance
     241  	{
     242  	  _Constness		_M_constness;
     243  	  _Iterator_state	_M_state;
     244  	  const void*		_M_sequence;
     245  	  const type_info*	_M_seq_type;
     246  	} _M_iterator;
     247  
     248  	// When _M_kind == __sequence
     249  	_Instance _M_sequence;
     250  
     251  	// When _M_kind == __integer
     252  	struct : _Named
     253  	{
     254  	  long			_M_value;
     255  	} _M_integer;
     256  
     257  	// When _M_kind == __string
     258  	struct : _Named
     259  	{
     260  	  const char*		_M_value;
     261  	} _M_string;
     262  
     263  	// When _M_kind == __instance
     264  	_Instance _M_instance;
     265  
     266  	// When _M_kind == __iterator_value_type
     267  	_Type _M_iterator_value_type;
     268        } _M_variant;
     269  
     270        _Parameter() : _M_kind(__unused_param), _M_variant() { }
     271  
     272        _Parameter(long __value, const char* __name)
     273        : _M_kind(__integer), _M_variant()
     274        {
     275  	_M_variant._M_integer._M_name = __name;
     276  	_M_variant._M_integer._M_value = __value;
     277        }
     278  
     279        _Parameter(const char* __value, const char* __name)
     280        : _M_kind(__string), _M_variant()
     281        {
     282  	_M_variant._M_string._M_name = __name;
     283  	_M_variant._M_string._M_value = __value;
     284        }
     285  
     286        template<typename _Iterator, typename _Sequence, typename _Category>
     287  	_Parameter(_Safe_iterator<_Iterator, _Sequence, _Category> const& __it,
     288  		   const char* __name, _Is_iterator)
     289  	: _M_kind(__iterator),  _M_variant()
     290  	{
     291  	  _M_variant._M_iterator._M_name = __name;
     292  	  _M_variant._M_iterator._M_address = std::__addressof(__it);
     293  	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(_Iterator);
     294  	  _M_variant._M_iterator._M_constness =
     295  	    __it._S_constant() ? __const_iterator : __mutable_iterator;
     296  	  _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
     297  	  _M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence);
     298  
     299  	  if (__it._M_singular())
     300  	    {
     301  	      if (__it._M_value_initialized())
     302  		_M_variant._M_iterator._M_state = __singular_value_init;
     303  	      else
     304  		_M_variant._M_iterator._M_state = __singular;
     305  	    }
     306  	  else
     307  	    {
     308  	      if (__it._M_is_before_begin())
     309  		_M_variant._M_iterator._M_state = __before_begin;
     310  	      else if (__it._M_is_end())
     311  		_M_variant._M_iterator._M_state = __end;
     312  	      else if (__it._M_is_begin())
     313  		_M_variant._M_iterator._M_state = __begin;
     314  	      else
     315  		_M_variant._M_iterator._M_state = __middle;
     316  	    }
     317  	}
     318  
     319        template<typename _Iterator, typename _Sequence>
     320  	_Parameter(_Safe_local_iterator<_Iterator, _Sequence> const& __it,
     321  		   const char* __name, _Is_iterator)
     322  	: _M_kind(__iterator),  _M_variant()
     323  	{
     324  	  _M_variant._M_iterator._M_name = __name;
     325  	  _M_variant._M_iterator._M_address = std::__addressof(__it);
     326  	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(_Iterator);
     327  	  _M_variant._M_iterator._M_constness =
     328  	    __it._S_constant() ? __const_iterator : __mutable_iterator;
     329  	  _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
     330  	  _M_variant._M_iterator._M_seq_type = _GLIBCXX_TYPEID(_Sequence);
     331  
     332  	  if (__it._M_singular())
     333  	    {
     334  	      if (__it._M_value_initialized())
     335  		_M_variant._M_iterator._M_state = __singular_value_init;
     336  	      else
     337  		_M_variant._M_iterator._M_state = __singular;
     338  	    }
     339  	  else
     340  	    {
     341  	      if (__it._M_is_end())
     342  		_M_variant._M_iterator._M_state = __end;
     343  	      else if (__it._M_is_begin())
     344  		_M_variant._M_iterator._M_state = __begin;
     345  	      else
     346  		_M_variant._M_iterator._M_state = __middle;
     347  	    }
     348  	}
     349  
     350        template<typename _Type>
     351  	_Parameter(const _Type* const& __it, const char* __name, _Is_iterator)
     352  	: _M_kind(__iterator), _M_variant()
     353  	{
     354  	  _M_variant._M_iterator._M_name = __name;
     355  	  _M_variant._M_iterator._M_address = std::__addressof(__it);
     356  	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
     357  	  _M_variant._M_iterator._M_constness = __const_iterator;
     358  	  _M_variant._M_iterator._M_state = __it ? __unknown_state : __singular;
     359  	  _M_variant._M_iterator._M_sequence = 0;
     360  	  _M_variant._M_iterator._M_seq_type = 0;
     361  	}
     362  
     363        template<typename _Type>
     364  	_Parameter(_Type* const& __it, const char* __name, _Is_iterator)
     365  	: _M_kind(__iterator), _M_variant()
     366  	{
     367  	  _M_variant._M_iterator._M_name = __name;
     368  	  _M_variant._M_iterator._M_address = std::__addressof(__it);
     369  	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
     370  	  _M_variant._M_iterator._M_constness = __mutable_iterator;
     371  	  _M_variant._M_iterator._M_state = __it ? __unknown_state : __singular;
     372  	  _M_variant._M_iterator._M_sequence = 0;
     373  	  _M_variant._M_iterator._M_seq_type = 0;
     374  	}
     375  
     376        template<typename _Iterator>
     377  	_Parameter(_Iterator const& __it, const char* __name, _Is_iterator)
     378  	: _M_kind(__iterator), _M_variant()
     379  	{
     380  	  _M_variant._M_iterator._M_name = __name;
     381  	  _M_variant._M_iterator._M_address = std::__addressof(__it);
     382  	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
     383  	  _M_variant._M_iterator._M_constness = __unknown_constness;
     384  	  _M_variant._M_iterator._M_state =
     385  	    __gnu_debug::__check_singular(__it) ? __singular : __unknown_state;
     386  	  _M_variant._M_iterator._M_sequence = 0;
     387  	  _M_variant._M_iterator._M_seq_type = 0;
     388  	}
     389  
     390  #if __cplusplus >= 201103L
     391        // The following constructors are only defined in C++11 to take
     392        // advantage of the constructor delegation feature.
     393        template<typename _Iterator, typename _Container>
     394          _Parameter(
     395  	  __gnu_cxx::__normal_iterator<_Iterator, _Container> const& __it,
     396  	const char* __name, _Is_iterator)
     397  	: _Parameter(__it.base(), __name, _Is_iterator{})
     398  	{ _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it); }
     399  
     400        template<typename _Iterator>
     401  	_Parameter(std::reverse_iterator<_Iterator> const& __it,
     402  		   const char* __name, _Is_iterator)
     403  	: _Parameter(__it.base(), __name, _Is_iterator{})
     404  	{
     405  	  _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it);
     406  	  _M_variant._M_iterator._M_state
     407  	    = _S_reverse_state(_M_variant._M_iterator._M_state);
     408  	}
     409  
     410        template<typename _Iterator, typename _Sequence, typename _Category>
     411  	_Parameter(std::reverse_iterator<_Safe_iterator<_Iterator, _Sequence,
     412  							_Category>> const& __it,
     413  	  const char* __name, _Is_iterator)
     414  	: _Parameter(__it.base(), __name, _Is_iterator{})
     415  	{
     416  	  _M_variant._M_iterator._M_type
     417  	    = _GLIBCXX_TYPEID(std::reverse_iterator<_Iterator>);
     418  	  _M_variant._M_iterator._M_state
     419  	    = _S_reverse_state(_M_variant._M_iterator._M_state);
     420  	}
     421  
     422        template<typename _Iterator>
     423  	_Parameter(std::move_iterator<_Iterator> const& __it,
     424  		   const char* __name, _Is_iterator)
     425  	: _Parameter(__it.base(), __name, _Is_iterator{})
     426  	{ _M_variant._M_iterator._M_type = _GLIBCXX_TYPEID(__it); }
     427  
     428        template<typename _Iterator, typename _Sequence, typename _Category>
     429  	_Parameter(std::move_iterator<_Safe_iterator<_Iterator, _Sequence,
     430  						     _Category>> const& __it,
     431  	  const char* __name, _Is_iterator)
     432  	: _Parameter(__it.base(), __name, _Is_iterator{})
     433        {
     434  	_M_variant._M_iterator._M_type
     435  	  = _GLIBCXX_TYPEID(std::move_iterator<_Iterator>);
     436        }
     437  
     438      private:
     439        _Iterator_state
     440        _S_reverse_state(_Iterator_state __state)
     441        {
     442  	  switch (__state)
     443  	    {
     444  	    case __begin:
     445  	      return __rend;
     446  	    case __middle:
     447  	      return __rmiddle;
     448  	    case __end:
     449  	      return __rbegin;
     450  	    default:
     451  	      return __state;
     452  	    }
     453        }
     454  
     455      public:
     456  #endif
     457  
     458        template<typename _Sequence>
     459  	_Parameter(const _Safe_sequence<_Sequence>& __seq,
     460  		   const char* __name, _Is_sequence)
     461  	: _M_kind(__sequence), _M_variant()
     462  	{
     463  	  _M_variant._M_sequence._M_name = __name;
     464  	  _M_variant._M_sequence._M_address =
     465  	    static_cast<const _Sequence*>(std::__addressof(__seq));
     466  	  _M_variant._M_sequence._M_type = _GLIBCXX_TYPEID(_Sequence);
     467  	}
     468  
     469        template<typename _Sequence>
     470  	_Parameter(const _Sequence& __seq, const char* __name, _Is_sequence)
     471  	: _M_kind(__sequence), _M_variant()
     472  	{
     473  	  _M_variant._M_sequence._M_name = __name;
     474  	  _M_variant._M_sequence._M_address = std::__addressof(__seq);
     475  	  _M_variant._M_sequence._M_type = _GLIBCXX_TYPEID(_Sequence);
     476  	}
     477  
     478        template<typename _Iterator>
     479  	_Parameter(const _Iterator& __it, const char* __name,
     480  		   _Is_iterator_value_type)
     481  	: _M_kind(__iterator_value_type), _M_variant()
     482  	{
     483  	  _M_variant._M_iterator_value_type._M_name = __name;
     484  	  _M_variant._M_iterator_value_type._M_type =
     485  	    _GLIBCXX_TYPEID(typename std::iterator_traits<_Iterator>::value_type);
     486  	}
     487  
     488        template<typename _Type>
     489  	_Parameter(const _Type& __inst, const char* __name, _Is_instance)
     490  	: _M_kind(__instance), _M_variant()
     491  	{
     492  	  _M_variant._M_instance._M_name = __name;
     493  	  _M_variant._M_instance._M_address = &__inst;
     494  	  _M_variant._M_instance._M_type = _GLIBCXX_TYPEID(_Type);
     495  	}
     496  
     497  #if !_GLIBCXX_INLINE_VERSION
     498        void
     499        _M_print_field(const _Error_formatter* __formatter,
     500  		     const char* __name) const _GLIBCXX_DEPRECATED;
     501  
     502        void
     503        _M_print_description(const _Error_formatter* __formatter)
     504  	const _GLIBCXX_DEPRECATED;
     505  #endif
     506      };
     507  
     508      template<typename _Iterator>
     509        _Error_formatter&
     510        _M_iterator(const _Iterator& __it, const char* __name = 0)
     511        {
     512  	if (_M_num_parameters < std::size_t(__max_parameters))
     513  	  _M_parameters[_M_num_parameters++] = _Parameter(__it, __name,
     514  							  _Is_iterator());
     515  	return *this;
     516        }
     517  
     518      template<typename _Iterator>
     519        _Error_formatter&
     520        _M_iterator_value_type(const _Iterator& __it,
     521  			     const char* __name = 0)
     522        {
     523  	if (_M_num_parameters < __max_parameters)
     524  	  _M_parameters[_M_num_parameters++] =
     525  	    _Parameter(__it, __name, _Is_iterator_value_type());
     526  	return *this;
     527        }
     528  
     529      _Error_formatter&
     530      _M_integer(long __value, const char* __name = 0)
     531      {
     532        if (_M_num_parameters < __max_parameters)
     533  	_M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
     534        return *this;
     535      }
     536  
     537      _Error_formatter&
     538      _M_string(const char* __value, const char* __name = 0)
     539      {
     540        if (_M_num_parameters < __max_parameters)
     541  	_M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
     542        return *this;
     543      }
     544  
     545      template<typename _Sequence>
     546        _Error_formatter&
     547        _M_sequence(const _Sequence& __seq, const char* __name = 0)
     548        {
     549  	if (_M_num_parameters < __max_parameters)
     550  	  _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name,
     551  							  _Is_sequence());
     552  	return *this;
     553        }
     554  
     555      template<typename _Type>
     556        _Error_formatter&
     557        _M_instance(const _Type& __inst, const char* __name = 0)
     558        {
     559  	if (_M_num_parameters < __max_parameters)
     560  	  _M_parameters[_M_num_parameters++] = _Parameter(__inst, __name,
     561  							  _Is_instance());
     562  	return *this;
     563        }
     564  
     565      _Error_formatter&
     566      _M_message(const char* __text)
     567      { _M_text = __text; return *this; }
     568  
     569      // Kept const qualifier for backward compatibility, to keep the same
     570      // exported symbol.
     571      _Error_formatter&
     572      _M_message(_Debug_msg_id __id) const throw ();
     573  
     574      _GLIBCXX_NORETURN void
     575      _M_error() const;
     576  
     577  #if !_GLIBCXX_INLINE_VERSION
     578      template<typename _Tp>
     579        void
     580        _M_format_word(char*, int, const char*, _Tp)
     581        const throw () _GLIBCXX_DEPRECATED;
     582  
     583      void
     584      _M_print_word(const char* __word) const _GLIBCXX_DEPRECATED;
     585  
     586      void
     587      _M_print_string(const char* __string) const _GLIBCXX_DEPRECATED;
     588  #endif
     589  
     590    private:
     591      _Error_formatter(const char* __file, unsigned int __line,
     592  		     const char* __function)
     593      : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0)
     594      , _M_function(__function)
     595  #if _GLIBCXX_HAVE_STACKTRACE
     596  # ifdef _GLIBCXX_DEBUG_BACKTRACE
     597      , _M_backtrace_state(__glibcxx_backtrace_create_state(0, 1, _S_err, 0))
     598      , _M_backtrace_full(&__glibcxx_backtrace_full)
     599  # else
     600      , _M_backtrace_state(0)
     601  # endif
     602  #endif
     603      { }
     604  
     605  #if !_GLIBCXX_INLINE_VERSION
     606      void
     607      _M_get_max_length() const throw () _GLIBCXX_DEPRECATED;
     608  #endif
     609  
     610      enum { __max_parameters = 9 };
     611  
     612      const char*		_M_file;
     613      unsigned int	_M_line;
     614      _Parameter		_M_parameters[__max_parameters];
     615      unsigned int	_M_num_parameters;
     616      const char*		_M_text;
     617      const char*		_M_function;
     618  #if _GLIBCXX_HAVE_STACKTRACE
     619      struct __glibcxx_backtrace_state*		_M_backtrace_state;
     620      // TODO: Remove _M_backtrace_full after __glibcxx_backtrace_full is moved
     621      // from libstdc++_libbacktrace.a to libstdc++.so:
     622      __decltype(&__glibcxx_backtrace_full)	_M_backtrace_full;
     623  
     624      static void _S_err(void*, const char*, int) { }
     625  #endif
     626  
     627    public:
     628      static _Error_formatter&
     629      _S_at(const char* __file, unsigned int __line, const char* __function)
     630      {
     631        static _Error_formatter __formatter(__file, __line, __function);
     632        return __formatter;
     633      }
     634    };
     635  } // namespace __gnu_debug
     636  
     637  #undef _GLIBCXX_TYPEID
     638  
     639  #endif