mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-06-28 16:17:28 -04:00
rsdebug supports variadic style for atomic log
This commit is contained in:
parent
968f234bfd
commit
2ae21ca800
1 changed files with 54 additions and 19 deletions
|
@ -46,6 +46,18 @@ struct t_RsLogger
|
||||||
{
|
{
|
||||||
inline t_RsLogger() = default;
|
inline t_RsLogger() = default;
|
||||||
|
|
||||||
|
/** Offer variadic style too, as a benefit this has better atomicity then
|
||||||
|
* << style, but doesn't supports manipulators and things like std::endl
|
||||||
|
* @see https://stackoverflow.com/a/27375675 */
|
||||||
|
template <typename Arg, typename... Args>
|
||||||
|
inline t_RsLogger(Arg&& arg, Args&&... args)
|
||||||
|
{
|
||||||
|
ostr << std::forward<Arg>(arg);
|
||||||
|
using expander = int[];
|
||||||
|
(void)expander{0, (void(ostr << std::forward<Args>(args)), 0)...};
|
||||||
|
mFlush();
|
||||||
|
}
|
||||||
|
|
||||||
/** On other platforms expose the type of underlying stream.
|
/** On other platforms expose the type of underlying stream.
|
||||||
* On Android it cannot work like that so return the class type itself
|
* On Android it cannot work like that so return the class type itself
|
||||||
* just for code compatibility with other platforms */
|
* just for code compatibility with other platforms */
|
||||||
|
@ -60,12 +72,7 @@ struct t_RsLogger
|
||||||
{
|
{
|
||||||
if(pf == static_cast<std::ostream& (*)(std::ostream&)>(
|
if(pf == static_cast<std::ostream& (*)(std::ostream&)>(
|
||||||
&std::endl< char, std::char_traits<char> > ))
|
&std::endl< char, std::char_traits<char> > ))
|
||||||
{
|
mFlush();
|
||||||
__android_log_write(
|
|
||||||
static_cast<int>(CATEGORY),
|
|
||||||
"RetroShare", ostr.str().c_str() );
|
|
||||||
ostr.str() = "";
|
|
||||||
}
|
|
||||||
else ostr << pf;
|
else ostr << pf;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -78,6 +85,14 @@ struct t_RsLogger
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
|
|
||||||
|
void mFlush()
|
||||||
|
{
|
||||||
|
__android_log_write(
|
||||||
|
static_cast<int>(CATEGORY),
|
||||||
|
"RetroShare", ostr.str().c_str() );
|
||||||
|
ostr.str() = "";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // def __ANDROID__
|
#else // def __ANDROID__
|
||||||
|
@ -99,38 +114,56 @@ enum class RsLoggerCategories
|
||||||
template <RsLoggerCategories CATEGORY>
|
template <RsLoggerCategories CATEGORY>
|
||||||
struct t_RsLogger
|
struct t_RsLogger
|
||||||
{
|
{
|
||||||
inline t_RsLogger() = default;
|
|
||||||
|
|
||||||
/// Expose the type of underlying stream
|
/// Expose the type of underlying stream
|
||||||
using stream_type = decltype(std::cerr);
|
using stream_type = decltype(std::cerr);
|
||||||
|
|
||||||
|
/// Return underlying stream to write avoiding additional prefixes
|
||||||
|
static inline stream_type& uStream() { return std::cerr; }
|
||||||
|
|
||||||
|
inline t_RsLogger() = default;
|
||||||
|
|
||||||
|
/** Offer variadic style too, as a benefit this has better atomicity then
|
||||||
|
* << style, but doesn't supports manipulators and things like std::endl
|
||||||
|
* @see https://stackoverflow.com/a/27375675 */
|
||||||
|
template <typename Arg, typename... Args>
|
||||||
|
inline t_RsLogger(Arg&& arg, Args&&... args)
|
||||||
|
{
|
||||||
|
std::ostringstream ostr;
|
||||||
|
ostr << getPrefix() << std::forward<Arg>(arg);
|
||||||
|
using expander = int[];
|
||||||
|
(void)expander{0, (void(ostr << std::forward<Args>(args)), 0)...};
|
||||||
|
ostr << std::endl;
|
||||||
|
uStream() << ostr.str();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline stream_type& operator<<(const T& val)
|
inline stream_type& operator<<(const T& val)
|
||||||
|
{ return uStream() << getPrefix() << val; }
|
||||||
|
|
||||||
|
/// needed for manipulators and things like std::endl
|
||||||
|
stream_type& operator<<(std::ostream& (*pf)(std::ostream&))
|
||||||
|
{ return uStream() << pf; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string getPrefix()
|
||||||
{
|
{
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
const auto now = system_clock::now();
|
const auto now = system_clock::now();
|
||||||
const auto sec = time_point_cast<seconds>(now);
|
const auto sec = time_point_cast<seconds>(now);
|
||||||
const auto msec = duration_cast<milliseconds>(now - sec);
|
const auto msec = duration_cast<milliseconds>(now - sec);
|
||||||
std::stringstream tstream;
|
std::ostringstream tstream;
|
||||||
tstream << static_cast<char>(CATEGORY) << " "
|
tstream << static_cast<char>(CATEGORY) << " "
|
||||||
<< sec.time_since_epoch().count() << "."
|
<< sec.time_since_epoch().count() << "."
|
||||||
<< std::setfill('0') << std::setw(3) << msec.count()
|
<< std::setfill('0') << std::setw(3) << msec.count()
|
||||||
<< " " << val;
|
<< " ";
|
||||||
return std::cerr << tstream.str();
|
return tstream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// needed for manipulators and things like std::endl
|
|
||||||
stream_type& operator<<(std::ostream& (*pf)(std::ostream&))
|
|
||||||
{ return std::cerr << pf; }
|
|
||||||
|
|
||||||
/// Return underlying stream to write avoiding additional prefixes
|
|
||||||
inline stream_type& uStream() const { return std::cerr; }
|
|
||||||
};
|
};
|
||||||
#endif // def __ANDROID__
|
#endif // def __ANDROID__
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comfortable debug message loggin, supports chaining like std::cerr but can
|
* Comfortable debug message logging, supports chaining like std::cerr but can
|
||||||
* be easly and selectively disabled at compile time to reduce generated binary
|
* be easly and selectively disabled at compile time to reduce generated binary
|
||||||
* size and performance impact without too many \#ifdef around.
|
* size and performance impact without too many \#ifdef around.
|
||||||
*
|
*
|
||||||
|
@ -190,6 +223,8 @@ struct RsNoDbg
|
||||||
{
|
{
|
||||||
inline RsNoDbg() = default;
|
inline RsNoDbg() = default;
|
||||||
|
|
||||||
|
template <typename T, typename... Args> inline RsNoDbg(T, Args...) {}
|
||||||
|
|
||||||
/** Defined as the type itself just for code compatibility with other
|
/** Defined as the type itself just for code compatibility with other
|
||||||
* logging classes */
|
* logging classes */
|
||||||
using stream_type = RsNoDbg;
|
using stream_type = RsNoDbg;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue