一些有用的c++ utility
#define ITEMSOF(arr) (sizeof(arr) / sizeof(0[arr]))
(0[arr]
is identical to arr[0]
for arrays but will
intentionally fail if it's used against a C++ object that overloads
operator[]
.)
The C++ version is less intuitive but more type-safe:
template<int n>
struct char_array_wrapper{
char result[n];
};
template<typename T, int s>
char_array_wrapper<s> the_type_of_the_variable_is_not_an_array(const T (&array)[s]){
}
#define ITEMSOF(v) sizeof(the_type_of_the_variable_is_not_an_array(v).result)
#ifdef NDEBUG
#define Dprintf ( format , ...)
#else
#define Dprintf ( format , ...) /
fprintf ( stderr , "[%s]:%s:%d: " format , __FILE__ , /
__func__ , __LINE__ , ##__VA_ARGS__)
#endif
class make_string
{
public :
template < typename T >
make_string & operator <<( T const & datum )
{
buffer_ << datum ;
return * this ;
}
operator std :: string () const
{
return buffer_ . str ();
}
private :
std :: ostringstream buffer_ ;
};
// usage:
void f ( std :: string const & );
int main ()
{
std :: string name = "David" ;
f ( make_string () << "Hello " << name << "!" );
}
class make_string
{
// ...
public :
operator const char * ()
{
return buffer_ . str (). c_str ();
}
};
inline std::string &rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int,
int>(std::isspace))).base(), s.end());
return s;
}
inline std::string <rim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
inline std::string &trim(std::string &s) {
return ltrim(rtrim(s));
}
template < class C >
class _StringBuffer
{
typename std :: basic_string < C > & m_str ;
typename std :: vector < C > m_buffer ;
public :
_StringBuffer ( std :: basic_string < C > & str , size_t nSize )
: m_str ( str ), m_buffer ( nSize + 1 ) { get ()[ nSize ] = ( C ) 0 ; }
~ _StringBuffer ()
{ commit (); }
C * get ()
{ return &( m_buffer [ 0 ]); }
operator C *()
{ return get (); }
void commit ()
{
if ( m_buffer . size () != 0 )
{
size_t l = std :: char_traits < C >:: length ( get ());
m_str . assign ( get (), l );
m_buffer . resize ( 0 );
}
}
void abort ()
{ m_buffer . resize ( 0 ); }
};
template < class C >
inline _StringBuffer < C > StringBuffer ( typename std :: basic_string < C > & str , size_t nSize )
{ return _StringBuffer < C >( str , nSize ); }
So now I can say:
std :: string str ;
GetWindowsDirectory ( StringBuffer ( str , MAX_PATH ), MAX_PATH );
A simple
hexdump
is often good to have...#include <ctype.h>
#include <stdio.h>
void hexdump ( void * ptr , int buflen ) {
unsigned char * buf = ( unsigned char *) ptr ;
int i , j ;
for ( i = 0 ; i < buflen ; i += 16 ) {
printf ( "%06x: " , i );
for ( j = 0 ; j < 16 ; j ++)
if ( i + j < buflen )
printf ( "%02x " , buf [ i + j ]);
else
printf ( " " );
printf ( " " );
for ( j = 0 ; j < 16 ; j ++)
if ( i + j < buflen )
printf ( "%c" , isprint ( buf [ i + j ]) ? buf [ i + j ] : '.' );
printf ( "/n" );
}
}