Showing posts with label Templates. Show all posts
Showing posts with label Templates. Show all posts

Monday, July 19, 2010

Printing useful STL container information with GDB

GDB's "p variable-name" is the Swiss Army knife of the programmer, except when it comes to examine the contents of STL containers.

(gdb) p fieldInd
$110 = {
  <std::_Vector_base<unsigned long, std::allocator<unsigned long> >> = {
    _M_impl = {
      <std::allocator<unsigned long>> = {
        <__gnu_cxx::new_allocator<unsigned long>> = {<No data fields>}, <No data fields>}, 
      members of std::_Vector_base<unsigned long, std::allocator<unsigned long> >::_Vector_impl: 
      _M_start = 0x646c60, 
      _M_finish = 0x646cc8, 
      _M_end_of_storage = 0x646d20
    }
  }, <No data fields>}

This tutorial gives you useful information to have GDB print useful STL container information for you.
(gdb) pvector perm
elem[0]: $111 = 4
elem[1]: $112 = 2
elem[2]: $113 = 0
elem[3]: $114 = 3
elem[4]: $115 = 1
elem[5]: $116 = 5
Vector size = 6
Vector capacity = 6
Element type = unsigned long *

Tuesday, December 08, 2009

Debug class implementation with templates

Here is the implementation of a debug reporting system in C++, with the same interface as cerr but with the plus of implementing a static debug level in your code.
template<int compiledDebugLevel>
class DebugCls {
  public:    /// Sends an object to the standard error.
    template<class T>
    DebugCls& operator<<(const T& a) const;
    /// Allows to use manipulators on the object.
    errorCls& operator<<(ostream& (*a)(ostream&));
    /// Allows to use the object as a function.
    DebugCls& operator()(const char* msg) const;
};

DebugCls<1> debug1; ///< Debug object for level 1.
DebugCls<4> debug4; ///< Debug object for level 4.
DebugCls<6> debug6; ///< Debug object for level 6.
DebugCls<10> debug10; ///< Debug object for level 10.

Reasonable limit for new neighbor requests which have fallen beyond the available memory for a person.
const int debugLevel = 0; ///< Chosen debug level for the current build.

template<int compiledDebugLevel>
template<class T>
DebugCls<compiledDebugLevel>& DebugCls<compiledDebugLevel>::operator<<(const T& a) const {
  if (compiledDebugLevel < debugLevel)
  cerr << a;
  return *this;
}

template<int compiledDebugLevel>

DebugCls<compiledDebugLevel>& DebugCls<compiledDebugLevel>::operator<<(ostream& (*a)(ostream&)) const {
  if (compiledDebugLevel < debugLevel)
  cerr << a;
  return *this;
}

template<int compiledDebugLevel>
DebugCls<compiledDebugLevel>& DebugCls<compiledDebugLevel>::operator()(const char* msg) const {
  if (compiledDebugLevel < debugLevel)
  cerr << "Program error: " << msg << "\n";
  return *this;
}
The functions have been written outline in this example so you get an idea of the required template nesting. However, these functions are short, so you might as well inline them.