home *** CD-ROM | disk | FTP | other *** search
/ Beginning C++ Through Gam…rogramming (2nd Edition) / BCGP2E.ISO / bloodshed / devcpp-4.9.9.2_setup.exe / formatter.h < prev    next >
C/C++ Source or Header  |  2005-01-29  |  11KB  |  392 lines

  1. // Debug-mode error formatting implementation -*- C++ -*-
  2.  
  3. // Copyright (C) 2003, 2004
  4. // Free Software Foundation, Inc.
  5. //
  6. // This file is part of the GNU ISO C++ Library.  This library is free
  7. // software; you can redistribute it and/or modify it under the
  8. // terms of the GNU General Public License as published by the
  9. // Free Software Foundation; either version 2, or (at your option)
  10. // any later version.
  11.  
  12. // This library is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. // GNU General Public License for more details.
  16.  
  17. // You should have received a copy of the GNU General Public License along
  18. // with this library; see the file COPYING.  If not, write to the Free
  19. // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  20. // USA.
  21.  
  22. // As a special exception, you may use this file as part of a free software
  23. // library without restriction.  Specifically, if other files instantiate
  24. // templates or use macros or inline functions from this file, or you compile
  25. // this file and link it with other files to produce an executable, this
  26. // file does not by itself cause the resulting executable to be covered by
  27. // the GNU General Public License.  This exception does not however
  28. // invalidate any other reasons why the executable file might be covered by
  29. // the GNU General Public License.
  30.  
  31. #ifndef _GLIBCXX_DEBUG_FORMATTER_H
  32. #define _GLIBCXX_DEBUG_FORMATTER_H 1
  33.  
  34. #include <typeinfo>
  35. #include <debug/debug.h>
  36.  
  37. namespace __gnu_debug
  38. {
  39.   using std::type_info;
  40.  
  41.   /** Determine if the two types are the same. */
  42.   template<typename _Type1, typename _Type2>
  43.     struct __is_same
  44.     {
  45.       static const bool value = false;
  46.     };
  47.  
  48.   template<typename _Type>
  49.     struct __is_same<_Type, _Type>
  50.     {
  51.       static const bool value = true;
  52.     };
  53.  
  54.   template<bool> struct __truth { };
  55.  
  56.   class _Safe_sequence_base;
  57.  
  58.   template<typename _Iterator, typename _Sequence>
  59.     class _Safe_iterator;
  60.  
  61.   template<typename _Sequence>
  62.     class _Safe_sequence;
  63.  
  64.   enum _Debug_msg_id
  65.   {
  66.     // General checks
  67.     __msg_valid_range,
  68.     __msg_insert_singular,
  69.     __msg_insert_different,
  70.     __msg_erase_bad,
  71.     __msg_erase_different,
  72.     __msg_subscript_oob,
  73.     __msg_empty,
  74.     __msg_unpartitioned,
  75.     __msg_unpartitioned_pred,
  76.     __msg_unsorted,
  77.     __msg_unsorted_pred,
  78.     __msg_not_heap,
  79.     __msg_not_heap_pred,
  80.     // std::bitset checks
  81.     __msg_bad_bitset_write,
  82.     __msg_bad_bitset_read,
  83.     __msg_bad_bitset_flip,
  84.     // std::list checks
  85.     __msg_self_splice,
  86.     __msg_splice_alloc,
  87.     __msg_splice_bad,
  88.     __msg_splice_other,
  89.     __msg_splice_overlap,
  90.     // iterator checks
  91.     __msg_init_singular,
  92.     __msg_init_copy_singular,
  93.     __msg_init_const_singular,
  94.     __msg_copy_singular,
  95.     __msg_bad_deref,
  96.     __msg_bad_inc,
  97.     __msg_bad_dec,
  98.     __msg_iter_subscript_oob,
  99.     __msg_advance_oob,
  100.     __msg_retreat_oob,
  101.     __msg_iter_compare_bad,
  102.     __msg_compare_different,
  103.     __msg_iter_order_bad,
  104.     __msg_order_different,
  105.     __msg_distance_bad,
  106.     __msg_distance_different,
  107.     // istream_iterator
  108.     __msg_deref_istream,
  109.     __msg_inc_istream,
  110.     // ostream_iterator
  111.     __msg_output_ostream,
  112.     // istreambuf_iterator
  113.     __msg_deref_istreambuf,
  114.     __msg_inc_istreambuf
  115.   };
  116.  
  117.   class _Error_formatter
  118.   {
  119.     /// Whether an iterator is constant, mutable, or unknown
  120.     enum _Constness
  121.     {
  122.       __unknown_constness,
  123.       __const_iterator,
  124.       __mutable_iterator,
  125.       __last_constness
  126.     };
  127.  
  128.     // The state of the iterator (fine-grained), if we know it.
  129.     enum _Iterator_state
  130.     {
  131.       __unknown_state,
  132.       __singular,      // singular, may still be attached to a sequence
  133.       __begin,         // dereferenceable, and at the beginning
  134.       __middle,        // dereferenceable, not at the beginning
  135.       __end,           // past-the-end, may be at beginning if sequence empty
  136.       __last_state
  137.     };
  138.  
  139.     // Tags denoting the type of parameter for construction
  140.     struct _Is_iterator { };
  141.     struct _Is_sequence { };
  142.  
  143.     // A parameter that may be referenced by an error message
  144.     struct _Parameter
  145.     {
  146.       enum
  147.       {
  148.     __unused_param,
  149.     __iterator,
  150.     __sequence,
  151.     __integer,
  152.     __string
  153.       } _M_kind;
  154.  
  155.       union
  156.       {
  157.     // When _M_kind == __iterator
  158.     struct
  159.     {
  160.       const char*      _M_name;
  161.       const void*      _M_address;
  162.       const type_info* _M_type;
  163.       _Constness       _M_constness;
  164.       _Iterator_state  _M_state;
  165.       const void*      _M_sequence;
  166.       const type_info* _M_seq_type;
  167.     } _M_iterator;
  168.  
  169.     // When _M_kind == __sequence
  170.     struct
  171.     {
  172.       const char*      _M_name;
  173.       const void*      _M_address;
  174.       const type_info* _M_type;
  175.     } _M_sequence;
  176.  
  177.     // When _M_kind == __integer
  178.     struct
  179.     {
  180.       const char* _M_name;
  181.       long        _M_value;
  182.     } _M_integer;
  183.  
  184.     // When _M_kind == __string
  185.     struct
  186.     {
  187.       const char* _M_name;
  188.       const char* _M_value;
  189.     } _M_string;
  190.       } _M_variant;
  191.  
  192.       _Parameter() : _M_kind(__unused_param), _M_variant() { }
  193.  
  194.       _Parameter(long __value, const char* __name) 
  195.       : _M_kind(__integer), _M_variant()
  196.       {
  197.     _M_variant._M_integer._M_name = __name;
  198.     _M_variant._M_integer._M_value = __value;
  199.       }
  200.  
  201.       _Parameter(const char* __value, const char* __name) 
  202.       : _M_kind(__string), _M_variant()
  203.       {
  204.     _M_variant._M_string._M_name = __name;
  205.     _M_variant._M_string._M_value = __value;
  206.       }
  207.  
  208.       template<typename _Iterator, typename _Sequence>
  209.         _Parameter(const _Safe_iterator<_Iterator, _Sequence>& __it,
  210.            const char* __name, _Is_iterator)
  211.     : _M_kind(__iterator),  _M_variant()
  212.         {
  213.       _M_variant._M_iterator._M_name = __name;
  214.       _M_variant._M_iterator._M_address = &__it;
  215.       _M_variant._M_iterator._M_type = &typeid(__it);
  216.       _M_variant._M_iterator._M_constness =
  217.         __is_same<_Safe_iterator<_Iterator, _Sequence>,
  218.                              typename _Sequence::iterator>::
  219.           value? __mutable_iterator : __const_iterator;
  220.       _M_variant._M_iterator._M_sequence = __it._M_get_sequence();
  221.       _M_variant._M_iterator._M_seq_type = &typeid(_Sequence);
  222.  
  223.       if (__it._M_singular())
  224.         _M_variant._M_iterator._M_state = __singular;
  225.       else
  226.         {
  227.           bool __is_begin = __it._M_is_begin();
  228.           bool __is_end = __it._M_is_end();
  229.           if (__is_end)
  230.         _M_variant._M_iterator._M_state = __end;
  231.           else if (__is_begin)
  232.         _M_variant._M_iterator._M_state = __begin;
  233.           else
  234.         _M_variant._M_iterator._M_state = __middle;
  235.         }
  236.     }
  237.  
  238.       template<typename _Type>
  239.         _Parameter(const _Type*& __it, const char* __name, _Is_iterator)
  240.         : _M_kind(__iterator), _M_variant()
  241.         {
  242.       _M_variant._M_iterator._M_name = __name;
  243.       _M_variant._M_iterator._M_address = &__it;
  244.       _M_variant._M_iterator._M_type = &typeid(__it);
  245.       _M_variant._M_iterator._M_constness = __mutable_iterator;
  246.       _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
  247.       _M_variant._M_iterator._M_sequence = 0;
  248.       _M_variant._M_iterator._M_seq_type = 0;
  249.     }
  250.  
  251.       template<typename _Type>
  252.         _Parameter(_Type*& __it, const char* __name, _Is_iterator)
  253.         : _M_kind(__iterator), _M_variant()
  254.         {
  255.       _M_variant._M_iterator._M_name = __name;
  256.       _M_variant._M_iterator._M_address = &__it;
  257.       _M_variant._M_iterator._M_type = &typeid(__it);
  258.       _M_variant._M_iterator._M_constness = __const_iterator;
  259.       _M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
  260.       _M_variant._M_iterator._M_sequence = 0;
  261.       _M_variant._M_iterator._M_seq_type = 0;
  262.     }
  263.  
  264.       template<typename _Iterator>
  265.         _Parameter(const _Iterator& __it, const char* __name, _Is_iterator)
  266.         : _M_kind(__iterator), _M_variant()
  267.         {
  268.       _M_variant._M_iterator._M_name = __name;
  269.       _M_variant._M_iterator._M_address = &__it;
  270.       _M_variant._M_iterator._M_type = &typeid(__it);
  271.       _M_variant._M_iterator._M_constness = __unknown_constness;
  272.       _M_variant._M_iterator._M_state =
  273.         __gnu_debug::__check_singular(__it)? __singular : __unknown_state;
  274.       _M_variant._M_iterator._M_sequence = 0;
  275.       _M_variant._M_iterator._M_seq_type = 0;
  276.     }
  277.  
  278.       template<typename _Sequence>
  279.         _Parameter(const _Safe_sequence<_Sequence>& __seq,
  280.            const char* __name, _Is_sequence)
  281.         : _M_kind(__sequence), _M_variant()
  282.         {
  283.       _M_variant._M_sequence._M_name = __name;
  284.       _M_variant._M_sequence._M_address =
  285.         static_cast<const _Sequence*>(&__seq);
  286.       _M_variant._M_sequence._M_type = &typeid(_Sequence);
  287.     }
  288.  
  289.       template<typename _Sequence>
  290.         _Parameter(const _Sequence& __seq, const char* __name, _Is_sequence)
  291.         : _M_kind(__sequence), _M_variant()
  292.         {
  293.       _M_variant._M_sequence._M_name = __name;
  294.       _M_variant._M_sequence._M_address = &__seq;
  295.       _M_variant._M_sequence._M_type = &typeid(_Sequence);
  296.     }
  297.  
  298.       void
  299.       _M_print_field(const _Error_formatter* __formatter,
  300.              const char* __name) const;
  301.  
  302.       void
  303.       _M_print_description(const _Error_formatter* __formatter) const;
  304.     };
  305.  
  306.     friend struct _Parameter;
  307.  
  308.   public:
  309.     template<typename _Iterator>
  310.       const _Error_formatter&
  311.       _M_iterator(const _Iterator& __it, const char* __name = 0)  const
  312.       {
  313.     if (_M_num_parameters < __max_parameters)
  314.       _M_parameters[_M_num_parameters++] = _Parameter(__it, __name,
  315.                               _Is_iterator());
  316.     return *this;
  317.       }
  318.  
  319.     const _Error_formatter&
  320.     _M_integer(long __value, const char* __name = 0) const
  321.     {
  322.       if (_M_num_parameters < __max_parameters)
  323.     _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
  324.       return *this;
  325.     }
  326.  
  327.     const _Error_formatter&
  328.     _M_string(const char* __value, const char* __name = 0) const
  329.     {
  330.       if (_M_num_parameters < __max_parameters)
  331.     _M_parameters[_M_num_parameters++] = _Parameter(__value, __name);
  332.       return *this;
  333.     }
  334.  
  335.     template<typename _Sequence>
  336.       const _Error_formatter&
  337.       _M_sequence(const _Sequence& __seq, const char* __name = 0) const
  338.       {
  339.     if (_M_num_parameters < __max_parameters)
  340.       _M_parameters[_M_num_parameters++] = _Parameter(__seq, __name,
  341.                               _Is_sequence());
  342.     return *this;
  343.       }
  344.  
  345.     const _Error_formatter&
  346.     _M_message(const char* __text) const
  347.     { _M_text = __text; return *this; }
  348.  
  349.     const _Error_formatter&
  350.     _M_message(_Debug_msg_id __id) const;
  351.  
  352.     void
  353.     _M_error() const;
  354.  
  355.   private:
  356.     _Error_formatter(const char* __file, size_t __line)
  357.     : _M_file(__file), _M_line(__line), _M_num_parameters(0), _M_text(0),
  358.       _M_max_length(78), _M_column(1), _M_first_line(true), _M_wordwrap(false)
  359.     { }
  360.  
  361.     template<typename _Tp>
  362.       void
  363.       _M_format_word(char*, int, const char*, _Tp) const;
  364.  
  365.     void
  366.     _M_print_word(const char* __word) const;
  367.  
  368.     void
  369.     _M_print_string(const char* __string) const;
  370.  
  371.     enum { __max_parameters = 9 };
  372.  
  373.     const char*         _M_file;
  374.     size_t              _M_line;
  375.     mutable _Parameter  _M_parameters[__max_parameters];
  376.     mutable size_t      _M_num_parameters;
  377.     mutable const char* _M_text;
  378.     mutable size_t      _M_max_length;
  379.     enum { _M_indent = 4 } ;
  380.     mutable size_t      _M_column;
  381.     mutable bool        _M_first_line;
  382.     mutable bool        _M_wordwrap;
  383.  
  384.   public:
  385.     static _Error_formatter
  386.     _M_at(const char* __file, size_t __line)
  387.     { return _Error_formatter(__file, __line); }
  388.   };
  389. } // namespace __gnu_debug
  390.  
  391. #endif
  392.