/*
* This file is part of the Omni C++ framework
*
* Copyright (c) 2016, Zeriph Enterprises, LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of Zeriph, Zeriph Enterprises, LLC, nor the names
* of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ZERIPH AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ZERIPH AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(OMNI_DELEGATE13_HPP)
#define OMNI_DELEGATE13_HPP 1
#include <omni/defs/delegate_def.hpp>
#include <omni/types/invoke_t.hpp>
namespace omni {
/**
* The delegate is a powerful function pointer object that
* encapsulates both an object instance and a method. The delegate is
* agnostic to the type or method it encapsulates; all that matters is that
* the method be signature compatible with the delegate. This allows for
* 'anonymous' invocation by users of the delegate.
*
* @tparam Ret Specifies the return type of the function the delegate is to attach to
* @tparam PT1 Specifies the 1st parameter type passed to the function delegate
* @tparam PT2 Specifies the 2nd parameter type passed to the function delegate
* @tparam PT3 Specifies the 3rd parameter type passed to the function delegate
* @tparam PT4 Specifies the 4th parameter type passed to the function delegate
* @tparam PT5 Specifies the 5th parameter type passed to the function delegate
* @tparam PT6 Specifies the 6th parameter type passed to the function delegate
* @tparam PT7 Specifies the 7th parameter type passed to the function delegate
* @tparam PT8 Specifies the 8th parameter type passed to the function delegate
* @tparam PT9 Specifies the 9th parameter type passed to the function delegate
* @tparam PT10 Specifies the 10th parameter type passed to the function delegate
* @tparam PT11 Specifies the 11th parameter type passed to the function delegate
* @tparam PT12 Specifies the 12th parameter type passed to the function delegate
* @tparam PT13 Specifies the 13th parameter type passed to the function delegate
*/
template <
typename Ret,
typename PT1,
typename PT2,
typename PT3,
typename PT4,
typename PT5,
typename PT6,
typename PT7,
typename PT8,
typename PT9,
typename PT10,
typename PT11,
typename PT12,
typename PT13 >
class delegate13
{
public:
/** Defines the return type this delegate will represent */
typedef Ret ret_t;
/** Defines the 1st function parameter type of this delegate */
typedef PT1 p1_t;
/** Defines the 2nd function parameter type of this delegate */
typedef PT2 p2_t;
/** Defines the 3rd function parameter type of this delegate */
typedef PT3 p3_t;
/** Defines the 4th function parameter type of this delegate */
typedef PT4 p4_t;
/** Defines the 5th function parameter type of this delegate */
typedef PT5 p5_t;
/** Defines the 6th function parameter type of this delegate */
typedef PT6 p6_t;
/** Defines the 7th function parameter type of this delegate */
typedef PT7 p7_t;
/** Defines the 8th function parameter type of this delegate */
typedef PT8 p8_t;
/** Defines the 9th function parameter type of this delegate */
typedef PT9 p9_t;
/** Defines the 10th function parameter type of this delegate */
typedef PT10 p10_t;
/** Defines the 11th function parameter type of this delegate */
typedef PT11 p11_t;
/** Defines the 12th function parameter type of this delegate */
typedef PT12 p12_t;
/** Defines the 13th function parameter type of this delegate */
typedef PT13 p13_t;
/** Defines the functor signature this delegate will represent */
typedef ret_t (*functor)(
void* extObj, p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13);
/** Defines the function pointer signature this delegate will represent */
typedef ret_t (*function_ptr)(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13);
/**
* The default constructor; constructs a default delegate
* object with no function or member attached.
*/
delegate13() :
OMNI_SAFE_DGATE_MILST_FW
m_method(
OMNI_NULL),
m_target(
OMNI_NULL)
{
OMNI_SAFE_DGATE_INIT_FW
OMNI_D5_FW(
"created delegate");
}
/**
* The copy constructor; copies another delegates target and method.
* The delegate being copied must be of the same signature.
*
* @param cp The other delegate to copy
*/
delegate13(
const delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& cp) :
OMNI_SAFE_DGATE_MILST_FW
m_method(cp.m_method),
m_target(cp.m_target)
{
OMNI_SAFE_DGATE_INIT_FW
OMNI_D5_FW(
"copied delegate");
}
/**
* Creates a new instance from a non-member or static member function pointer.
*
* @param fnptr The function pointer to attach
*/
delegate13(function_ptr fnptr) :
OMNI_SAFE_DGATE_MILST_FW
m_method(
reinterpret_cast<functor>(fnptr)),
m_target(
OMNI_NULL)
{
OMNI_SAFE_DGATE_INIT_FW
OMNI_D5_FW(
"created delegate with function pointer");
}
/**
* Creates a new instance from a functor and object.
*
* @param obj The instance of the object to use with this delegate
* @param mthd The functor of the object to attach to this delegate for invocation
*/
delegate13(
void* obj, functor mthd) :
OMNI_SAFE_DGATE_MILST_FW
m_method(mthd),
m_target(obj)
{
OMNI_SAFE_DGATE_INIT_FW
OMNI_D5_FW(
"created delegate with target and method");
}
/** The default destructor, detaches this instance from its target and method */
~delegate13()
{
OMNI_TRY_FW
this->unbind();
OMNI_SAFE_DGATE_DTOR_FW
OMNI_CATCH_FW
OMNI_D5_FW(
"destroyed");
}
/**
* Attach a static member or non-member function to this delegate.
*
* @param fnptr The function taking 13 parameters to attach to the delegate
*/
inline void bond(function_ptr fnptr)
{
this->_bind(
OMNI_NULL,
reinterpret_cast<functor>(fnptr));
}
/**
* Attach a static member or non-member function to this delegate.
*
* @tparam fnptr The function taking 13 parameters to attach to the delegate
*/
template < ret_t (*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t) >
inline void bond()
{
this->_bind(
OMNI_NULL, &_anon_param_fn<fnptr>);
}
/**
* Attach a member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t) >
inline void bond(T& obj)
{
this->_bind(
static_cast<
void*>(&obj), &_member_param_fn<T, fnptr>);
}
/**
* Attach a member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t) >
inline void bond(
const T& obj)
{
this->_bind(
static_cast<
void*>(
const_cast<T*>(&obj)), &_member_param_fn<T, fnptr>);
}
/**
* Attach a member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t) >
inline void bond(
const T *
const obj)
{
this->_bind(
static_cast<
void*>(
const_cast<T *
const>(obj)), &_member_param_fn<T, fnptr>);
}
/**
* Attach a const member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The const function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t)
const >
inline void bond_const(
const T& obj)
{
this->_bind(
static_cast<
void*>(
const_cast<T*>(&obj)), &_member_param_fn_const<T, fnptr>);
}
/**
* Attach a const member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t)
const >
inline void bond_const(
const T *
const obj)
{
this->_bind(
static_cast<
void*>(
const_cast<T *
const>(obj)), &_member_param_fn_const<T, fnptr>);
}
/**
* Attach a static member or non-member function to this delegate.
*
* @tparam fnptr The function taking 13 parameters to attach to the delegate
*/
template < ret_t (*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t) >
static delegate13 bind()
{
return delegate13(
OMNI_NULL, &_anon_param_fn<fnptr>);
}
/**
* Attach a parametrized member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The parametrized function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t) >
static delegate13 bind(T& obj)
{
return delegate13(&obj, &_member_param_fn<T, fnptr>);
}
/**
* Attach a parametrized member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The parametrized function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t) >
static delegate13 bind(
const T& obj)
{
return delegate13(
const_cast<T *
const>(&obj), &_member_param_fn<T, fnptr>);
}
/**
* Attach a parametrized member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The parametrized function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t) >
static delegate13 bind(
const T *
const obj)
{
return delegate13(
const_cast<T *
const>(obj), &_member_param_fn<T, fnptr>);
}
/**
* Attach a const parametrized member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The parametrized function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t)
const >
static delegate13 bind_const(
const T& obj)
{
return delegate13(
const_cast<T *
const>(&obj), &_member_param_fn_const<T, fnptr>);
}
/**
* Attach a parametrized member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The parametrized function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t)
const >
static delegate13 bind_const(
const T *
const obj)
{
return delegate13(
const_cast<T *
const>(obj), &_member_param_fn_const<T, fnptr>);
}
/**
* Gets if this instance is bound to a method
*
* @return True if this instance is currently bound
*/
bool is_bound()
const
{
OMNI_SAFE_DGATE_ALOCK_FW
return (
this->m_method !=
OMNI_NULL);
}
/**
* Gets if this instance is bound to a member method
*
* @return True if this instance is currently bound to a target and method
*/
bool is_member_bound()
const
{
OMNI_SAFE_DGATE_ALOCK_FW
return (
this->m_method !=
OMNI_NULL &&
this->m_target !=
OMNI_NULL);
}
/**
* Invoke the function bound to this delegate instance
*
* @return This function returns whatever is returned
* (if anything) from the invoked function
*/
ret_t invoke(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13)
const
{
#if defined(OMNI_SAFE_DELEGATES)
omni::sync::mutex_lock(
this->m_mtx);
if (
this->m_method !=
OMNI_NULL) {
if (
this->m_target ==
OMNI_NULL) {
function_ptr fp =
reinterpret_cast<function_ptr>(
this->m_method);
omni::sync::mutex_unlock(
this->m_mtx);
return (*fp)(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13);
}
else {
functor m =
this->m_method;
void* t =
this->m_target;
omni::sync::mutex_unlock(
this->m_mtx);
return (*m)(t, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13);
}
}
omni::sync::mutex_unlock(
this->m_mtx);
#else
return (
this->m_target ==
OMNI_NULL ?
(*
reinterpret_cast<function_ptr>(
this->m_method))(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13) :
(*
this->m_method)(
this->m_target, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13));
#endif
OMNI_ERR_RETV_FW(
"No valid function has been assigned to the delegate",
omni::invalid_delegate(), ret_t())
}
/**
* Invoke the function bound to this delegate instance.
* This method does not preform any safety checks on the
* method or object instance and directly calls the method
* for invocation (if bound).
*
* @return This function returns whatever is returned
* (if anything) from the invoked function
*/
ret_t invoke_direct(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13)
const
{
return (
this->m_target ==
OMNI_NULL ?
(*
reinterpret_cast<function_ptr>(
this->m_method))(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13) :
(*
this->m_method)(
this->m_target, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13));
}
/**
omni::invoke_t invoke_type()
const
{
OMNI_SAFE_DGATE_ALOCK_FW
if (
this->m_method ==
OMNI_NULL) {
return omni::invoke_type::NONE; }
return (
this->m_target ==
OMNI_NULL ?
omni::invoke_type::ANONYMOUS :
omni::invoke_type::MEMBER_FUNC);
}
/**
* Gets the underlying functor called when this method is invoked.
*
* @return The underlying functor method
*/
const functor method()
const
{
OMNI_SAFE_DGATE_ALOCK_FW
return this->m_method;
}
/**
* Gets the underlying function pointer called when this method is invoked.
*
*
@return The underlying function pointer, or an
OMNI_NULL value if the
* object instance is null;
*/
const function_ptr function()
const
{
OMNI_SAFE_DGATE_ALOCK_FW
return ((
this->m_target ==
OMNI_NULL) ?
reinterpret_cast<function_ptr>(
this->m_method) :
OMNI_NULL);
}
/**
* Swaps the invocation method and target of 2 delegates
*/
void swap(delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& d)
{
OMNI_SAFE_DGATE_ALOCK_FW
#if defined(OMNI_SAFE_DELEGATES)
omni::sync::mutex_lock(d.m_mtx);
#endif
std::swap(
this->m_target, d.m_target);
std::swap(
this->m_method, d.m_method);
#if defined(OMNI_SAFE_DELEGATES)
omni::sync::mutex_unlock(d.m_mtx);
#endif
}
/**
* Gets the underlying target (if any) used when invoking this method.
*
* @return A pointer to the underlying target object (if any)
*/
void *
const target()
const
{
OMNI_SAFE_DGATE_ALOCK_FW
return this->m_target;
}
/**
* Detaches the target and method from this instance
*/
inline void unbind()
{
this->_bind(
OMNI_NULL,
OMNI_NULL);
OMNI_D4_FW(
"instance unbound");
}
/**
* Checks if the current delegate instance is valid
*
* @return True if the instance has a method attached, false if not
*/
bool valid()
const
{
OMNI_SAFE_DGATE_ALOCK_FW
return (
this->m_method !=
OMNI_NULL);
}
/**
* Has the same effect as calling the invoke method.
* Overloading this operator makes it such that you can
* use the delegate as if it were a function.
*
* delegate<int> d = &some_func;
* printf("value = %d", d());
*
* @return The return type specified at compile time
*/
inline ret_t
operator()(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13)
const
{
return this->invoke(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13);
}
/**
* The boolean operator allows you to check for validity as if
* the delegate were a function pointer, example:
* delegate<int> d;
* if (d) { d(); } // fails check because d is not attached
* d = &some_func;
* if (d) { d(); } // success because d is bound
*
* @return True if the delegate is attached
*/
inline operator bool()
const
{
return this->valid();
}
/**
* The negated boolean () operator is used to check negation of the boolean () operator
*/
inline bool operator!()
const
{
return !(
this->
operator bool());
}
/**
* The assignment operator is used to set the target and method
* of another delegate to this one.
*
* @param d The right most operand which to assign to
*
* @return A reference to the current instance
*/
delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >&
operator=(
const delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& d)
{
if (
this != &d) {
#if defined(OMNI_SAFE_DELEGATES)
omni::sync::mutex_lock(d.m_mtx);
#endif
this->_bind(d.m_target, d.m_method);
#if defined(OMNI_SAFE_DELEGATES)
omni::sync::mutex_unlock(d.m_mtx);
#endif
}
return *
this;
}
/**
* Allows for assignment to anonymous (non-member) functions
* by saying = &func_name
*
* @param fp The function pointer to assign
*
* @return A reference to the current instance
*/
delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >&
operator=(function_ptr fnptr)
{
this->_bind(
OMNI_NULL,
reinterpret_cast<functor>(fnptr));
return *
this;
}
/**
* The equality operator test the target and method against the other
*
* @param d The right most operand which to compare to
*
* @return True if the two instance are equal
*/
bool operator==(
const delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& d)
const
{
if (
this == &d) {
return true; }
OMNI_SAFE_DGATE_ALOCK_FW
return
(
this->m_target == d.m_target &&
this->m_method == d.m_method
);
}
/**
* The != operator is used for comparison results (negates the == operator)
*
* @param d The right most operand which to compare to
*
* @return True if the instances are not equal
*/
bool operator!=(
const delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& d)
const
{
return !(*
this == d);
}
private:
OMNI_SAFE_DGATE_MTX_FW
/** The 13 parameter member function to be called */
functor m_method;
/** The instance of the object set when attaching to the delegate */
void* m_target;
/**
* The internal binding function that sets the underlying method and target
*
* @param obj The target to set
* @param mthd The method to set
* @param type The type to set
*/
void _bind(
void* obj, functor mthd)
{
OMNI_SAFE_DGATE_ALOCK_FW
this->m_target = obj;
this->m_method = mthd;
}
/**
* Gets the parametrized non member (static/anonymous) function to use
*
* @tparam fnptr The method to assign
*/
template < ret_t (*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t) >
static ret_t _anon_param_fn(
void*, p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13)
{
return (fnptr)(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13);
}
/**
* Get the parametrized member function to use
*
* @tparam T The class type
* @tparam fnptr The parametrized member method to use
* @param obj The instance object associated with the member method
*
* @return The functor
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t) >
static ret_t _member_param_fn(
void* obj, p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13)
{
return ((
static_cast<T*>(obj))->*
reinterpret_cast<ret_t (T::*)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t,
void*)>(fnptr))(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, obj);
}
/**
* Get the const parametrized member function to use
*
* @tparam T The class type
* @tparam fnptr The parametrized member method to use
* @param obj The instance object associated with the member method
*
* @return The functor
*/
template <
class T, ret_t (T::*fnptr)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t)
const >
static ret_t _member_param_fn_const(
void* obj, p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13)
{
return ((
static_cast<T*>(obj))->*
reinterpret_cast<ret_t (T::*)(p1_t, p2_t, p3_t, p4_t, p5_t, p6_t, p7_t, p8_t, p9_t, p10_t, p11_t, p12_t, p13_t,
void*)
const>(fnptr))(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, obj);
}
};
/** A generic delegate that has 13 parameters and does not return a value. */
typedef omni::delegate13<
void,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*> callback13;
/**
* The templated event allows client code to attach multiple delegates
* and invoke them, providing notification to attached code (i.e. event handlers).
*
* Invoking an event will invoke each attached handler (delegate) in the order
* they have been attached.
*
* @tparam Ret Specifies the return type of the delegates to be attached
* @tparam 13 Specifies the parameter types passed to the delegate
*/
template <
typename Ret,
typename PT1,
typename PT2,
typename PT3,
typename PT4,
typename PT5,
typename PT6,
typename PT7,
typename PT8,
typename PT9,
typename PT10,
typename PT11,
typename PT12,
typename PT13 >
class event13
{
public:
/** Defines the return type this event will represent */
typedef Ret ret_t;
/** Defines the delegate signature this event represents */
typedef omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 > delegate_t;
/** Defines the container type used by this event class */
typedef typename std::deque<
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 > > container_t;
/** Defines an iterator type to the underlying types */
typedef typename std::deque<
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 > >::iterator iterator_t;
/** Defines a const iterator type to the underlying types */
typedef typename std::deque<
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 > >::const_iterator const_iterator_t;
/** Defines a reverse iterator type to the underlying types */
typedef typename std::reverse_iterator< iterator_t > reverse_iterator_t;
/** Defines a const reverse iterator type to the underlying types */
typedef typename std::reverse_iterator< const_iterator_t > const_reverse_iterator_t;
/** Defines the 1st function parameter type of this delegate */
typedef PT1 p1_t;
/** Defines the 2nd function parameter type of this delegate */
typedef PT2 p2_t;
/** Defines the 3rd function parameter type of this delegate */
typedef PT3 p3_t;
/** Defines the 4th function parameter type of this delegate */
typedef PT4 p4_t;
/** Defines the 5th function parameter type of this delegate */
typedef PT5 p5_t;
/** Defines the 6th function parameter type of this delegate */
typedef PT6 p6_t;
/** Defines the 7th function parameter type of this delegate */
typedef PT7 p7_t;
/** Defines the 8th function parameter type of this delegate */
typedef PT8 p8_t;
/** Defines the 9th function parameter type of this delegate */
typedef PT9 p9_t;
/** Defines the 10th function parameter type of this delegate */
typedef PT10 p10_t;
/** Defines the 11th function parameter type of this delegate */
typedef PT11 p11_t;
/** Defines the 12th function parameter type of this delegate */
typedef PT12 p12_t;
/** Defines the 13th function parameter type of this delegate */
typedef PT13 p13_t;
/** The default constructor */
event13() :
OMNI_SAFE_EVENT_MILST_FW
m_list()
{
OMNI_SAFE_EVENT_INIT_FW
OMNI_D5_FW(
"created event");
}
/**
* The copy constructor copies the elements from the
* event passed in.
*
* @param cp The event to copy
*/
event13(
const event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& cp) :
OMNI_SAFE_EVENT_MILST_FW
m_list(cp.m_list)
{
OMNI_SAFE_EVENT_INIT_FW
OMNI_D5_FW(
"created event");
}
/**
* Creates an event with a signature compatible delegate attached
*
* @param d The signature compatible delegate to add to the invocation list
*/
explicit event13(
const omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& d) :
OMNI_SAFE_EVENT_MILST_FW
m_list()
{
OMNI_SAFE_EVENT_INIT_FW
this->attach(d);
OMNI_D5_FW(
"created event");
}
/**
* The default destructor; clears the underlying list,
* calling the destructor for each attached delegate
*/
~event13()
{
OMNI_TRY_FW
this->clear();
OMNI_SAFE_EVENT_DTOR_FW
OMNI_CATCH_FW
OMNI_D5_FW(
"destroyed");
}
/**
* Add (attach) a member delegate to this event instance
*
* @param d The member delegate to attach
*/
void attach(
const omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& d)
{
/* DEV_NOTE: don't check if 'd' doesn't have a valid function reference
since on invoke 'd' would fail if it didn't have a valid fnptr */
OMNI_SAFE_EVENT_ALOCK_FW
this->m_list.push_back(d);
}
/**
* Add (attach) another events invocation list to this instance
*
* @param e The other event to add invocation list
*/
void attach(
const event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& e)
{
if (
this != &e) {
OMNI_SAFE_EVENT_ALOCK_FW
container_t tmp = e.invocation_list();
for (iterator_t it = tmp.begin(); it != tmp.end(); it++) {
this->m_list.push_back(*it);
}
}
}
/**
* Add (attach) a range of delegates to this event instance
*
* @param begin The input iterator pointing to the initial position in the sequence to add
* @param end The input iterator pointing to the last position in the sequence to add
*/
template <
class InputIterator >
void attach(InputIterator begin, InputIterator end)
{
OMNI_SAFE_EVENT_ALOCK_FW
while (begin != end) {
this->m_list.push_back(*begin);
++begin;
}
}
/**
* Attach a an anonymous/non-member or static member function to this delegate.
*
* @tparam fnptr The function to attach to the delegate
*/
template < ret_t (*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
void attach()
{
this->attach( fnptr );
}
/**
* Attach a member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
void attach(T& obj)
{
this->attach(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind< T, fnptr >(obj) );
}
/**
* Attach a member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
void attach(
const T& obj)
{
this->attach(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind< T, fnptr >(obj) );
}
/**
* Attach a member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
void attach(
const T *
const obj)
{
this->attach(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind< T, fnptr >(obj) );
}
/**
* Attach a const member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13)
const >
void attach_const(
const T& obj)
{
this->attach(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind_const< T, fnptr >(obj) );
}
/**
* Attach a const member function to this delegate.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*/
template <
class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13)
const >
void attach_const(
const T *
const obj)
{
this->attach(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind_const< T, fnptr >(obj) );
}
/**
* Clears the underlying invocation list
*/
void clear()
{
OMNI_SAFE_EVENT_ALOCK_FW
// clear the list container, calling the items destructors
this->m_list.clear();
}
/**
* Tests if a specified member delegate is in this event instance.
*
* @param d The member delegate to search for
*
* @return True if the delegate is found, false otherwise
*/
bool contains(
const omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& d)
{
OMNI_SAFE_EVENT_ALOCK_FW
return (
this->_find(d) !=
this->m_list.end());
}
/**
* Tests if a specified member delegate is in this event instance.
*
* @tparam fnptr The function to attach to the delegate
*
* @return True if the delegate is found, false otherwise
*/
template < ret_t (*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
bool contains()
{
return this->contains( fnptr );
}
/**
* Tests if a specified member delegate is in this event instance.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*
* @return True if the delegate is found, false otherwise
*/
template <
class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
bool contains(T& obj)
{
return this->contains(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind< T, fnptr >(obj) );
}
/**
* Tests if a specified member delegate is in this event instance.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*
* @return True if the delegate is found, false otherwise
*/
template <
class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
bool contains(
const T& obj)
{
return this->contains(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind< T, fnptr >(obj) );
}
/**
* Tests if a specified member delegate is in this event instance.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*
* @return True if the delegate is found, false otherwise
*/
template <
class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
bool contains(
const T *
const obj)
{
return this->contains(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind< T, fnptr >(obj) );
}
/**
* Tests if a specified member delegate is in this event instance.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*
* @return True if the delegate is found, false otherwise
*/
template <
class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13)
const >
bool contains_const(
const T& obj)
{
return this->contains(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind_const< T, fnptr >(obj) );
}
/**
* Tests if a specified member delegate is in this event instance.
*
* @tparam T The type of class to associate with this delegate
* @tparam fnptr The function to attach to the delegate
* @param obj The instance of the class to reference in this delegate
*
* @return True if the delegate is found, false otherwise
*/
template <
class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13)
const >
bool contains_const(
const T *
const obj)
{
return this->contains(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind_const< T, fnptr >(obj) );
}
/**
* Detach a member delegate to this event instance
*
* @param d The member delegate to detach
*/
void detach(
const omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& d)
{
OMNI_SAFE_EVENT_ALOCK_FW
iterator_t found;
while ((found =
this->_find(d)) !=
this->m_list.end()) {
this->m_list.erase(found);
}
}
/**
* Detaches another events invocation list from this instance
*
* @param e The event to detach invocation list of
*/
void detach(
const event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& e)
{
if (
this != &e) {
OMNI_SAFE_EVENT_ALOCK_FW
iterator_t found =
this->m_list.end();
container_t tmp = e.invocation_list();
for (iterator_t it = tmp.begin(); it != tmp.end(); ++it) {
while ((found =
this->_find(*it)) !=
this->m_list.end()) {
this->m_list.erase(found);
}
}
}
}
/**
* Detach a range of delegates from this event instance
*
* @param begin The input iterator pointing to the initial position in the sequence to remove
* @param end The input iterator pointing to the last position in the sequence to remove
*/
template <
class InputIterator >
void detach(InputIterator begin, InputIterator end)
{
OMNI_SAFE_EVENT_ALOCK_FW
iterator_t found =
this->m_list.end();
while (begin != end) {
while ((found =
this->_find(*begin)) !=
this->m_list.end()) {
this->m_list.erase(found);
}
++begin;
}
}
/**
* Detach an anonymous/non-member or static member function from this event.
*
* @tparam fnptr The function to detach
*/
template < ret_t (*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
void detach()
{
this->detach( fnptr );
}
/**
* Detach a member function from this event.
*
* @tparam T The type of class to associate with the delegate
* @tparam fnptr The function to detach
* @param obj The instance of the class to reference
*/
template <
class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
void detach(T& obj)
{
this->detach(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind< T, fnptr >(obj) );
}
/**
* Detach a member function from this event.
*
* @tparam T The type of class to associate with the delegate
* @tparam fnptr The function to detach
* @param obj The instance of the class to reference
*/
template <
class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
void detach(
const T& obj)
{
this->detach(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind< T, fnptr >(obj) );
}
/**
* Detach a member function from this event.
*
* @tparam T The type of class to associate with the delegate
* @tparam fnptr The function to detach
* @param obj The instance of the class to reference
*/
template <
class T, Ret (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13) >
void detach(
const T *
const obj)
{
this->detach(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind< T, fnptr >(obj) );
}
/**
* Detach a const member function from this event.
*
* @tparam T The type of class to associate with the delegate
* @tparam fnptr The function to detach
* @param obj The instance of the class to reference
*/
template <
class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13)
const >
void detach_const(
const T& obj)
{
this->detach(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind_const< T, fnptr >(obj) );
}
/**
* Detach a const member function from this event.
*
* @tparam T The type of class to associate with the delegate
* @tparam fnptr The function to detach
* @param obj The instance of the class to reference
*/
template <
class T, ret_t (T::*fnptr)(PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13)
const >
void detach_const(
const T *
const obj)
{
this->detach(
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >::
template bind_const< T, fnptr >(obj) );
}
/**
* Checks if the current event instance has any attached methods
*
* @return True if the instance has a method or methods attached, false if not
*/
bool empty()
const
{
OMNI_SAFE_EVENT_ALOCK_FW
return this->m_list.empty();
}
/**
* Gets the invocation list used to call the delegate objects on event invocation
*
* @return The underlying container variable
*/
container_t invocation_list()
const
{
OMNI_SAFE_EVENT_ALOCK_FW
return this->m_list;
}
/**
* Calls the functions bound to this event instance in a non-safe manner.
* delegate::invoke_direct does not perform certain checks.
*
* @return The return type specified at compile time
*/
ret_t invoke_direct(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13)
const
{
OMNI_SAFE_EVENT_LOCK_FW
const_iterator_t cur =
this->m_list.begin();
const_iterator_t tmp =
this->m_list.begin();
const_iterator_t end =
this->m_list.end();
while (cur != end) {
if ((++tmp) == end) {
OMNI_SAFE_EVENT_UNLOCK_FW
return cur->invoke_direct(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13);
}
OMNI_SAFE_EVENT_UNLOCK_FW
cur->invoke_direct(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13);
OMNI_SAFE_EVENT_LOCK_FW
tmp = (++cur);
}
OMNI_SAFE_EVENT_UNLOCK_FW
}
void swap(event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& e)
{
OMNI_SAFE_EVENT_ALOCK_FW
#if defined(OMNI_SAFE_EVENTS)
omni::sync::mutex_lock(e.m_mtx);
#endif
std::swap(
this->m_list, e.m_list);
#if defined(OMNI_SAFE_EVENTS)
omni::sync::mutex_unlock(e.m_mtx);
#endif
}
/**
* The () operator can be used to call the functions bound to this event instance
*
* @return The return type specified at compile time
*/
ret_t
operator()(p1_t val1, p2_t val2, p3_t val3, p4_t val4, p5_t val5, p6_t val6, p7_t val7, p8_t val8, p9_t val9, p10_t val10, p11_t val11, p12_t val12, p13_t val13)
const
{
OMNI_SAFE_EVENT_LOCK_FW
const_iterator_t cur =
this->m_list.begin();
const_iterator_t tmp =
this->m_list.begin();
const_iterator_t end =
this->m_list.end();
while (cur != end) {
if ((++tmp) == end) {
OMNI_SAFE_EVENT_UNLOCK_FW
return cur->invoke(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13);
}
OMNI_SAFE_EVENT_UNLOCK_FW
cur->invoke(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13);
OMNI_SAFE_EVENT_LOCK_FW
tmp = (++cur);
}
OMNI_SAFE_EVENT_UNLOCK_FW
}
/**
* The boolean () operator can be used to check if this delegate is valid (has a valid function assigned)
*/
operator bool()
const
{
return !
this->empty();
}
/**
* The negated boolean () operator is used to check negation of the boolean () operator
*/
bool operator!()
const
{
return (!
operator bool());
}
/**
* The = operator is used to assign one event invocation to another
*
* @param e The right most operand event to assign
*/
event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >&
operator=(
const event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& e)
{
if (
this != &e) {
OMNI_SAFE_EVENT_ALOCK_FW
this->m_list.clear();
#if defined(OMNI_SAFE_EVENTS)
omni::sync::mutex_lock(e.m_mtx);
#endif
this->m_list = e.m_list;
#if defined(OMNI_SAFE_EVENTS)
omni::sync::mutex_unlock(e.m_mtx);
#endif
}
return *
this;
}
/**
* The [int] operator can be used to access a specific delegate in the
* invocation list directly.
*
* @return A reference to the delegate instance at the specified index
*/
omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >&
operator[](std::size_t idx)
{
OMNI_SAFE_EVENT_ALOCK_FW
if (
this->m_list.empty() || (idx > (
this->m_list.size() -
1))) {
OMNI_ERR_RETV_FW(
"Index out of range",
omni::index_out_of_range(),
NULL)
}
return *(
this->m_list[idx]);
}
/**
* The += operator is used to add delegates to this event instance
*
* @param d The right most operand delegate to add
*/
event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >&
operator+=(
const omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& d)
{
this->attach(d);
return *
this;
}
/**
* The += operator is used to add delegates to this event instance
*
* @param e The right most operand event to add
*/
event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >&
operator+=(
const event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& e)
{
this->attach(e);
return *
this;
}
/**
* The -= operator is used to remove delegates from this event instance
*
* @param d The right most operand delegate to remove
*/
event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >&
operator-=(
const omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& d)
{
this->detach(d);
return *
this;
}
/**
* The -= operator is used to remove delegates from this event instance
*
* @param e The right most operand event to remove
*/
event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >&
operator-=(
const event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& e)
{
this->detach(e);
return *
this;
}
/**
* The == operator is used for comparison results
*
* @param d The right most operand which to compare to
*/
bool operator==(
const event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& e)
const
{
if (
this == &e) {
return true; }
OMNI_SAFE_EVENT_ALOCK_FW
container_t l = e.invocation_list();
bool ret = (l.size() ==
this->m_list.size());
if (ret) {
const_iterator_t a =
this->m_list.begin();
const_iterator_t b = l.begin();
while ((a !=
this->m_list.end()) && (b != l.end())) {
if (*a != *b) { ret =
false;
break; }
++a; ++b;
}
}
return ret;
}
/**
* The != operator is used for comparison results (negates the == operator)
*
* @param d The right most operand which to compare to
*/
bool operator!=(
const event13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& e)
const
{
return !(*
this == e);
}
private:
OMNI_SAFE_EVENT_MTX_FW
/** The collection of member methods */
container_t m_list;
/**
* Find a specified member delegate in this event instance.
*
* @param d The member delegate to search for
*
* @return An iterator to the found delegate, list.end() if not found
*/
iterator_t _find(
const omni::delegate13< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13 >& d)
{
// don't use any locks here as calling code does the lock
if (
this->m_list.empty()) {
return this->m_list.end(); }
iterator_t itr =
this->m_list.end();
while (itr !=
this->m_list.begin()) {
if (*(--itr) == d) {
return itr; }
}
return this->m_list.end();
}
};
/** A generic event that has 13 parameters and does not return a value. */
typedef omni::event13<
void,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*> action13;
}
// namespace omni
#define OMNI_BIND13(Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, Class, Function, Obj) omni::delegate13<Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13>::bind<Class, &Class::Function>(Obj)
#define OMNI_BIND13_CONST(Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, Class, Function, Obj) omni::delegate13<Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13>::bind_const<Class, &Class::Function>(Obj)
namespace std {
template <
typename Ret,
typename PT1,
typename PT2,
typename PT3,
typename PT4,
typename PT5,
typename PT6,
typename PT7,
typename PT8,
typename PT9,
typename PT10,
typename PT11,
typename PT12,
typename PT13 >
inline void swap(
omni::delegate13<Ret,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*>& d1,
omni::delegate13<Ret,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*>& d2)
{
d1.swap(d2);
}
template <
typename Ret,
typename PT1,
typename PT2,
typename PT3,
typename PT4,
typename PT5,
typename PT6,
typename PT7,
typename PT8,
typename PT9,
typename PT10,
typename PT11,
typename PT12,
typename PT13 >
inline void swap(
omni::event13<Ret,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*>& e1,
omni::event13<Ret,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*>& e2)
{
e1.swap(e2);
}
}
#endif // OMNI_DELEGATE13_HPP