//*****************************************************************************
// RCF - Remote Call Framework
// Copyright (c) 2005. All rights reserved.
// Developed by Jarl Lindrud.
// Contact: jlindrud@hotmail.com .
//*****************************************************************************
#ifndef INCLUDE_RCF_TOOLS_HPP
#define INCLUDE_RCF_TOOLS_HPP
// Various utilities
#include <time.h>
#include <deque>
#include <iostream>
#include <iterator>
#include <memory>
#include <stdexcept>
#include <typeinfo>
#include <vector>
#include <boost/bind.hpp>
#include <boost/current_function.hpp>
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <RCF/Exception.hpp>
#include <RCF/ScopeGuard.h>
#include <RCF/ThreadLibrary.hpp>
#include <RCF/util/Meta.hpp>
#include <RCF/util/UnusedVariable.hpp>
// Assertion mechanism
#include <RCF/util/Assert.hpp>
#define RCF_ASSERT(x) UTIL_ASSERT(x, RCF::AssertionFailureException)
// Verification mechanism
#include <RCF/util/Throw.hpp>
#define RCF_VERIFY(x, msg) UTIL_VERIFY(x, RCF::VerificationFailureException, msg)
// Trace mechanism
#include <RCF/util/Trace.hpp>
//#define RCF_TRACE(x) DUMMY_VARIABLE_ARG_MACRO()
#define RCF_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[0]))
#define RCF1_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[1]))
#define RCF2_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[2]))
#define RCF3_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[3]))
#define RCF4_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[4]))
#define RCF5_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[5]))
#define RCF6_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[6]))
#define RCF7_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[7]))
#define RCF8_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[8]))
#define RCF9_TRACE(x) UTIL_TRACE(x, (*::RCF::pTraceChannels[9]))
namespace RCF {
extern util::TraceChannel *pTraceChannels[10];
}
// Throw mechanism
#include <RCF/util/Throw.hpp>
#define RCF_THROW UTIL_THROW
// Scope guard mechanism
namespace RCF {
class SharedPtrScopeGuard : boost::noncopyable
{
public:
template<typename T>
SharedPtrScopeGuard(T &t) :
spv(static_cast<void*>(NULL), t)
{}
template<typename T, typename R>
SharedPtrScopeGuard(T &t, R (T::*pfn)() ) :
spv(static_cast<void*>(NULL), boost::bind(pfn, &t))
{}
template<typename T, typename R, typename A>
SharedPtrScopeGuard(T &t, R (T::*pfn)(A), A a) :
spv(static_cast<void*>(NULL), boost::bind(pfn, &t, a))
{}
void dismiss()
{
spv.reset();
}
private:
boost::shared_ptr<void> spv;
};
/*
template<typename PFN>
void trigger0(void *pv)
{
((PFN) pv)();
}
template<typename T, typename PMFN>
void trigger1(void *pvt, void *pvmfn)
{
PMFN pmfn = (PMFN) pvmfn;
T *pt = (T *) pvt;
pt->*pmfn();
}
class AlexandrescuScopeGuard
{
public:
template<typename PFN>
AlexandrescuScopeGuard(PFN pfn) :
mTrigger0( trigger0<PFN> ),
mTrigger1(),
mpv0(pfn),
mpv1(),
mDismissed()
{}
template<typename T, typename PMFN>
AlexandrescuScopeGuard(T &t, PMFN pmfn) :
mTrigger1( trigger1<T, PMFN> ),
mpv0(&t),
mpv1( (void *) pmfn)
{}
~AlexandrescuScopeGuard()
{
if (!mDismissed)
{
try
{
if (mTrigger0)
{
mTrigger0(mpv0);
}
else if (mTrigger1)
{
mTrigger1(mpv0, mpv1);
}
}
catch(...)
{}
}
}
void dismiss()
{
mDismissed = true;
}
private:
bool mDismissed;
void (*mTrigger0)(void *pv0);
void (*mTrigger1)(void *pv0, void *pv1);
void *mpv0;
void *mpv1;
};
//#ifdef __BORLANDC__
// typedef SharedPtrScopeGuard ScopeGuard;
//#else
typedef AlexandrescuScopeGuard ScopeGuard;
//#endif
*/
}
#ifndef __BORLANDC__
namespace std {
#endif
// Trace std::vector
template<typename T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v)
{
os << "(";
std::copy(v.begin(), v.end(), std::ostream_iterator<T>(os, ", "));
os << ")";
return os;
}
// Trace std::deque
template<typename T>
std::ostream &operator<<(std::ostream &os, const std::deque<T> &d)
{
os << "(";
std::copy(d.begin(), d.end(), std::ostream_iterator<T>(os, ", "));
os << ")";
return os;
}
// Trace type_info
inline std::ostream &operator<<(std::ostream &os, const std::type_info &ti)
{
return os << ti.name();
}
// Trace exception
inline std::ostream &operator<<(std::ostream &os, const std::exception &e)
{
return os << "Type: " << typeid(e).name() << ", What: " << e.what();
}
#ifndef __BORLANDC__
} // namespace std
#endif
namespace RCF {
// Time in ms since ca 1970, modulo 65536 s (turns over every ~18.2 hrs).
unsigned int getCurrentTimeMs();
// Generate a timeout value for the given ending time.
// Returns zero if endTime <= current time <= endTime+10%of timer resolution, otherwise returns a nonzero duration in ms.
// Timer resolution as above (18.2 hrs).
unsigned int generateTimeoutMs(unsigned int endTimeMs);
} // namespace RCF
#endif // ! INCLUDE_RCF_TOOLS_HPP