175 lines
5.1 KiB
C++
175 lines
5.1 KiB
C++
/*
|
|
* Copyright (C) 2012 Intel Corporation
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) version 3.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301 USA
|
|
*/
|
|
|
|
/**
|
|
* Including this header file allows to use boost::bind() with
|
|
* a class member as first parameter and a boost::weak_ptr
|
|
* as second parameter.
|
|
*
|
|
* When the functor is invoked, it will lock the instance
|
|
* and only call the member if that succeeds. Otherwise it
|
|
* will silently return to the caller.
|
|
*
|
|
* The member function must have "void" as return value.
|
|
*
|
|
* This behavior makes sense in particular with asynchronous method
|
|
* calls where the result is only relevant while the caller still
|
|
* exists.
|
|
*
|
|
* The code is inspired by
|
|
* http://permalink.gmane.org/gmane.comp.lib.boost.user/70276 and was
|
|
* adapted to the SyncEvolution namespace and coding style. In contrast
|
|
* to that code, the shared_ptr is kept until the invoker gets freed.
|
|
* Seems a bit safer that way. Instead of duplicating the ->* operator
|
|
* in WeakPtrAdapter it uses the type of the member as template parameter
|
|
* to cover all kinds of members.
|
|
*/
|
|
|
|
#ifndef INCL_SYNCEVOLUTION_BOOST_HELPER
|
|
# define INCL_SYNCEVOLUTION_BOOST_HELPER
|
|
|
|
#include <boost/bind.hpp>
|
|
#include <boost/smart_ptr.hpp>
|
|
|
|
#include <syncevo/declarations.h>
|
|
SE_BEGIN_CXX
|
|
|
|
template <typename P, typename M>
|
|
class WeakPtrInvoker
|
|
{
|
|
public:
|
|
WeakPtrInvoker(const P &ptr, const M &member) :
|
|
m_ptr(ptr),
|
|
m_member(member)
|
|
{}
|
|
|
|
void operator()() const
|
|
{
|
|
if (m_ptr) {
|
|
(boost::get_pointer(m_ptr)->*m_member)();
|
|
}
|
|
}
|
|
|
|
template <typename A1>
|
|
void operator()(A1 a1) const
|
|
{
|
|
if (m_ptr) {
|
|
(boost::get_pointer(m_ptr)->*m_member)(a1);
|
|
}
|
|
}
|
|
|
|
template <typename A1, typename A2>
|
|
void operator()(A1 a1, A2 a2) const
|
|
{
|
|
if (m_ptr) {
|
|
(boost::get_pointer(m_ptr)->*m_member)(a1, a2);
|
|
}
|
|
}
|
|
|
|
template <typename A1, typename A2, typename A3>
|
|
void operator()(A1 a1, A2 a2, A3 a3) const
|
|
{
|
|
if (m_ptr) {
|
|
(boost::get_pointer(m_ptr)->*m_member)(a1, a2, a3);
|
|
}
|
|
}
|
|
|
|
template <typename A1, typename A2, typename A3, typename A4>
|
|
void operator()(A1 a1, A2 a2, A3 a3, A4 a4) const
|
|
{
|
|
if (m_ptr) {
|
|
(boost::get_pointer(m_ptr)->*m_member)(a1, a2, a3, a4);
|
|
}
|
|
}
|
|
|
|
template <typename A1, typename A2, typename A3, typename A4, typename A5>
|
|
void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
|
|
{
|
|
if (m_ptr) {
|
|
(boost::get_pointer(m_ptr)->*m_member)(a1, a2, a3, a4, a5);
|
|
}
|
|
}
|
|
|
|
template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
|
|
void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
|
|
{
|
|
if (m_ptr) {
|
|
(boost::get_pointer(m_ptr)->*m_member)(a1, a2, a3, a4, a5, a6);
|
|
}
|
|
}
|
|
|
|
template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
|
|
void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
|
|
{
|
|
if (m_ptr) {
|
|
(boost::get_pointer(m_ptr)->*m_member)(a1, a2, a3, a4, a5, a6, a7);
|
|
}
|
|
}
|
|
|
|
template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
|
|
void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
|
|
{
|
|
if (m_ptr) {
|
|
(boost::get_pointer(m_ptr)->*m_member)(a1, a2, a3, a4, a5, a6, a7, a8);
|
|
}
|
|
}
|
|
|
|
template <typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
|
|
void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const
|
|
{
|
|
if (m_ptr) {
|
|
(boost::get_pointer(m_ptr)->*m_member)(a1, a2, a3, a4, a5, a6, a7, a8, a9);
|
|
}
|
|
}
|
|
|
|
private:
|
|
P m_ptr;
|
|
M m_member;
|
|
};
|
|
|
|
template <typename T> class WeakPtrAdapter
|
|
{
|
|
public:
|
|
WeakPtrAdapter(const boost::shared_ptr<T> &ptr) :
|
|
m_ptr(ptr)
|
|
{}
|
|
|
|
template <typename M>
|
|
WeakPtrInvoker<boost::shared_ptr<T>, M> operator->*(M member) const
|
|
{
|
|
return WeakPtrInvoker<boost::shared_ptr<T>, M>(m_ptr, member);
|
|
}
|
|
|
|
private:
|
|
boost::shared_ptr<T> m_ptr;
|
|
};
|
|
|
|
SE_END_CXX
|
|
|
|
namespace boost
|
|
{
|
|
template<class T>
|
|
SyncEvo::WeakPtrAdapter<T> get_pointer(const boost::weak_ptr<T> &ptr)
|
|
{
|
|
return SyncEvo::WeakPtrAdapter<T>(ptr.lock());
|
|
}
|
|
}
|
|
|
|
#endif // INCL_SYNCEVOLUTION_BOOST_HELPER
|