一些有用的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"
);
}
}