//****************************************************************************** // RCF - Remote Call Framework // Copyright (c) 2005 - 2007. All rights reserved. // Consult your license for conditions of use. // Developed by Jarl Lindrud. // Contact: jlindrud@hotmail.com . //****************************************************************************** #ifndef INCLUDE_UTIL_VARIABLEARGMACRO_HPP #define INCLUDE_UTIL_VARIABLEARGMACRO_HPP #include #include #include #include "Platform/OS/GetCurrentTime.hpp" #include "Platform/OS/ThreadId.hpp" namespace util { class VariableArgMacroFunctor : boost::noncopyable { public: virtual ~VariableArgMacroFunctor() {} VariableArgMacroFunctor &init( const std::string &label, const std::string &msg, const char *file, int line, const char *func) { unsigned int timestamp = Platform::OS::getCurrentTimeMs(); int threadid = Platform::OS::GetCurrentThreadId(); header << file << "(" << line << "): " << func << ": " << ": Thread-id=" << threadid << " : Timestamp(ms)=" << timestamp << ": " << label << msg << ": " ; return *this; } void deinit() { args << std::endl; } template void notify(const T &t, const char *name) { args << name << "=" << t << ", "; } void notify(size_t t, const char *name) { args << name << "=" << static_cast(t) << ", "; } #if defined(_MSC_VER) && _MSC_VER <= 1200 void notify(__int64 t, const char *name) { //args << name << "=" << t << ", "; } #endif // TODO: fix this properly #ifdef _UNICODE void notify(const wchar_t *, const char *) { /*TODO*/ } void notify(const std::wstring &, const char *) { /*TODO*/ } #endif template T &cast() { return dynamic_cast(*this); } template T &cast(T *) { return dynamic_cast(*this); } std::ostringstream header; std::ostringstream args; }; class DummyVariableArgMacroObject { public: template DummyVariableArgMacroObject &operator()(const T &) { return *this; } }; #define DUMMY_VARIABLE_ARG_MACRO() \ if (false) ::util::DummyVariableArgMacroObject() } // namespace util #define DECLARE_VARIABLE_ARG_MACRO(macro_name, functor) \ DECLARE_VARIABLE_ARG_MACRO_(macro_name, macro_name##_A, macro_name##_B, functor) #define DECLARE_VARIABLE_ARG_MACRO_( macro_name, macro_name_A, macro_name_B, functor) \ template \ class VariableArgMacro; \ \ template<> class \ VariableArgMacro< functor > : public functor \ { \ public: \ VariableArgMacro() : \ macro_name_A(*this), macro_name_B(*this) \ {} \ template \ VariableArgMacro(const T1 &t1) : \ functor(t1), macro_name_A(*this), macro_name_B(*this) \ {} \ template \ VariableArgMacro(const T1 &t1, const T2 &t2) : \ functor(t1,t2), macro_name_A(*this), macro_name_B(*this) \ {} \ template \ VariableArgMacro(const T1 &t1, T2 &t2) : \ functor(t1,t2), macro_name_A(*this), macro_name_B(*this) \ {} \ ~VariableArgMacro() \ { \ functor::deinit(); \ } \ VariableArgMacro ¯o_name_A; \ VariableArgMacro ¯o_name_B; \ template \ VariableArgMacro< functor > ¬ify_(const T &t, const char *name) \ { \ notify(t,name); return *this; \ } \ VariableArgMacro< functor > ¬ify_(size_t t, const char *name) \ { \ functor::notify(t,name); return *this; \ } \ } #define DECLARE_VARIABLE_ARG_MACRO_T1( macro_name, functor ) \ DECLARE_VARIABLE_ARG_MACRO_T1_(macro_name, macro_name##_A, macro_name##_B, functor) #define DECLARE_VARIABLE_ARG_MACRO_T1_( macro_name, macro_name_A, macro_name_B, functor) \ template \ class VariableArgMacro; \ \ template \ class VariableArgMacro< functor > : public functor \ { \ public: \ VariableArgMacro() : \ macro_name_A(*this), macro_name_B(*this) \ {} \ template \ VariableArgMacro(const T1 &t1) : \ functor(t1), macro_name_A(*this), macro_name_B(*this) \ {} \ template \ VariableArgMacro(const T1 &t1, const T2 &t2) : \ functor(t1,t2), macro_name_A(*this), macro_name_B(*this) \ {} \ ~VariableArgMacro() \ { \ functor::deinit(); \ } \ VariableArgMacro ¯o_name_A; \ VariableArgMacro ¯o_name_B; \ template \ VariableArgMacro< functor > ¬ify_(const T &t, const char *name) \ { \ notify(t,name); \ return *this; \ } \ VariableArgMacro< functor > ¬ify_(size_t t, const char *name) \ { \ functor::notify(t,name); \ return *this; \ } \ } #define DECLARE_VARIABLE_ARG_MACRO_T2( macro_name, functor ) \ DECLARE_VARIABLE_ARG_MACRO_T2_(macro_name, macro_name##_A, macro_name##_B, functor) #define DECLARE_VARIABLE_ARG_MACRO_T2_( macro_name, macro_name_A, macro_name_B, functor) \ template \ class VariableArgMacro; \ \ template \ class VariableArgMacro< functor > : public functor \ { \ public: \ VariableArgMacro() : \ macro_name_A(*this), macro_name_B(*this) \ {} \ template \ VariableArgMacro(const T1 &t1) : \ functor(t1), macro_name_A(*this), macro_name_B(*this) \ {} \ template \ VariableArgMacro(const T1 &t1, const T2 &t2) : \ functor(t1,t2), macro_name_A(*this), macro_name_B(*this) \ {} \ ~VariableArgMacro() \ { \ functor::deinit(); \ } \ VariableArgMacro ¯o_name_A; \ VariableArgMacro ¯o_name_B; \ template \ VariableArgMacro< functor > ¬ify_(const T &t, const char *name) \ { \ notify(t,name); \ return *this; \ } \ VariableArgMacro< functor > ¬ify_(size_t t, const char *name) \ { \ functor::notify(t,name); \ return *this; \ } \ } #endif // ! INCLUDE_UTIL_VARIABLEARGMACRO_HPP