/*
* 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_DELEGATE16_HPP)
#define OMNI_DELEGATE16_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
* @tparam PT14 Specifies the 14th parameter type passed to the function delegate
* @tparam PT15 Specifies the 15th parameter type passed to the function delegate
* @tparam PT16 Specifies the 16th 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,
typename PT14,
typename PT15,
typename PT16 >
class delegate16
{
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 14th function parameter type of this delegate */
typedef PT14 p14_t;
/** Defines the 15th function parameter type of this delegate */
typedef PT15 p15_t;
/** Defines the 16th function parameter type of this delegate */
typedef PT16 p16_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, p14_t val14, p15_t val15, p16_t val16);
/** 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, p14_t val14, p15_t val15, p16_t val16);
/**
* The default constructor; constructs a default delegate
* object with no function or member attached.
*/
delegate16() :
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
*/
delegate16(
const delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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
*/
delegate16(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
*/
delegate16(
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 */
~delegate16()
{
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 16 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 16 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, p14_t, p15_t, p16_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, p14_t, p15_t, p16_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, p14_t, p15_t, p16_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, p14_t, p15_t, p16_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, p14_t, p15_t, p16_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, p14_t, p15_t, p16_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 16 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, p14_t, p15_t, p16_t) >
static delegate16 bind()
{
return delegate16(
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, p14_t, p15_t, p16_t) >
static delegate16 bind(T& obj)
{
return delegate16(&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, p14_t, p15_t, p16_t) >
static delegate16 bind(
const T& obj)
{
return delegate16(
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, p14_t, p15_t, p16_t) >
static delegate16 bind(
const T *
const obj)
{
return delegate16(
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, p14_t, p15_t, p16_t)
const >
static delegate16 bind_const(
const T& obj)
{
return delegate16(
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, p14_t, p15_t, p16_t)
const >
static delegate16 bind_const(
const T *
const obj)
{
return delegate16(
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, p14_t val14, p15_t val15, p16_t val16)
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, val14, val15, val16);
}
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, val14, val15, val16);
}
}
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, val14, val15, val16) :
(*
this->m_method)(
this->m_target, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16));
#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, p14_t val14, p15_t val15, p16_t val16)
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, val14, val15, val16) :
(*
this->m_method)(
this->m_target, val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16));
}
/**
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(delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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, p14_t val14, p15_t val15, p16_t val16)
const
{
return this->invoke(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
}
/**
* 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
*/
delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >&
operator=(
const delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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
*/
delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >&
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 delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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 delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& d)
const
{
return !(*
this == d);
}
private:
OMNI_SAFE_DGATE_MTX_FW
/** The 16 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, p14_t, p15_t, p16_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, p14_t val14, p15_t val15, p16_t val16)
{
return (fnptr)(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
}
/**
* 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, p14_t, p15_t, p16_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, p14_t val14, p15_t val15, p16_t val16)
{
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, p14_t, p15_t, p16_t,
void*)>(fnptr))(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16, 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, p14_t, p15_t, p16_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, p14_t val14, p15_t val15, p16_t val16)
{
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, p14_t, p15_t, p16_t,
void*)
const>(fnptr))(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16, obj);
}
};
/** A generic delegate that has 16 parameters and does not return a value. */
typedef omni::delegate16<
void,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*> callback16;
/**
* 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 16 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,
typename PT14,
typename PT15,
typename PT16 >
class event16
{
public:
/** Defines the return type this event will represent */
typedef Ret ret_t;
/** Defines the delegate signature this event represents */
typedef omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 > delegate_t;
/** Defines the container type used by this event class */
typedef typename std::deque<
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 > > container_t;
/** Defines an iterator type to the underlying types */
typedef typename std::deque<
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 > >::iterator iterator_t;
/** Defines a const iterator type to the underlying types */
typedef typename std::deque<
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 > >::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;
/** Defines the 14th function parameter type of this delegate */
typedef PT14 p14_t;
/** Defines the 15th function parameter type of this delegate */
typedef PT15 p15_t;
/** Defines the 16th function parameter type of this delegate */
typedef PT16 p16_t;
/** The default constructor */
event16() :
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
*/
event16(
const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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 event16(
const omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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
*/
~event16()
{
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::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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 event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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, PT14, PT15, PT16) >
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, PT14, PT15, PT16) >
void attach(T& obj)
{
this->attach(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16) >
void attach(
const T& obj)
{
this->attach(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16) >
void attach(
const T *
const obj)
{
this->attach(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16)
const >
void attach_const(
const T& obj)
{
this->attach(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16)
const >
void attach_const(
const T *
const obj)
{
this->attach(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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, PT14, PT15, PT16) >
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, PT14, PT15, PT16) >
bool contains(T& obj)
{
return this->contains(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16) >
bool contains(
const T& obj)
{
return this->contains(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16) >
bool contains(
const T *
const obj)
{
return this->contains(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16)
const >
bool contains_const(
const T& obj)
{
return this->contains(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16)
const >
bool contains_const(
const T *
const obj)
{
return this->contains(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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 event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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, PT14, PT15, PT16) >
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, PT14, PT15, PT16) >
void detach(T& obj)
{
this->detach(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16) >
void detach(
const T& obj)
{
this->detach(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16) >
void detach(
const T *
const obj)
{
this->detach(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16)
const >
void detach_const(
const T& obj)
{
this->detach(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, PT14, PT15, PT16)
const >
void detach_const(
const T *
const obj)
{
this->detach(
omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >::
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, p14_t val14, p15_t val15, p16_t val16)
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, val14, val15, val16);
}
OMNI_SAFE_EVENT_UNLOCK_FW
cur->invoke_direct(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
OMNI_SAFE_EVENT_LOCK_FW
tmp = (++cur);
}
OMNI_SAFE_EVENT_UNLOCK_FW
}
void swap(event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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, p14_t val14, p15_t val15, p16_t val16)
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, val14, val15, val16);
}
OMNI_SAFE_EVENT_UNLOCK_FW
cur->invoke(val1, val2, val3, val4, val5, val6, val7, val8, val9, val10, val11, val12, val13, val14, val15, val16);
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
*/
event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >&
operator=(
const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >&
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
*/
event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >&
operator+=(
const omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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
*/
event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >&
operator+=(
const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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
*/
event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >&
operator-=(
const omni::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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
*/
event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >&
operator-=(
const event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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 event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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 event16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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::delegate16< Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16 >& 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 16 parameters and does not return a value. */
typedef omni::event16<
void,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*> action16;
}
// namespace omni
#define OMNI_BIND16(Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16, Class, Function, Obj) omni::delegate16<Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16>::bind<Class, &Class::Function>(Obj)
#define OMNI_BIND16_CONST(Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16, Class, Function, Obj) omni::delegate16<Ret, PT1, PT2, PT3, PT4, PT5, PT6, PT7, PT8, PT9, PT10, PT11, PT12, PT13, PT14, PT15, PT16>::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,
typename PT14,
typename PT15,
typename PT16 >
inline void swap(
omni::delegate16<Ret,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*>& d1,
omni::delegate16<Ret,
void*,
void*,
void*,
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,
typename PT14,
typename PT15,
typename PT16 >
inline void swap(
omni::event16<Ret,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*>& e1,
omni::event16<Ret,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*,
void*>& e2)
{
e1.swap(e2);
}
}
#endif // OMNI_DELEGATE16_HPP