393 std::vector < std::function < result_t(arguments_t...)>>
functions;
402 bool completed_synchronously()
const noexcept override;
403 bool is_completed()
const noexcept override;
415 using function_t = std::function < result_t(arguments_t...) >;
439 delegate(
const no_arguments_function_t& function)
noexcept {data_->no_arguments_functions.push_back(function);}
445 template <
class object1_t,
class object2_t >
446 delegate(
const object1_t&
object, result_t(object2_t::*method)()
const) noexcept {
447 data_->functions.push_back(
function_t(std::bind(method,
const_cast < object1_t*
> (&
object))));
453 template <
class object1_t,
class object2_t >
454 delegate(
const object1_t&
object, result_t(object2_t::*method)()) noexcept {
455 data_->functions.push_back(
function_t(std::bind(method,
const_cast < object1_t*
> (&
object))));
460 template <
class object1_t,
class object2_t,
class a1_t >
461 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t)
const)
noexcept {
462 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1)));
465 template <
class object1_t,
class object2_t,
class a1_t >
466 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t))
noexcept {
467 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1)));
470 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t >
471 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t)
const)
noexcept {
472 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2)));
475 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t >
476 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t))
noexcept {
477 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2)));
480 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t >
481 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t)
const)
noexcept {
482 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
485 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t >
486 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t))
noexcept {
487 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
490 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t >
491 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t)
const) {
492 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)));
495 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t >
496 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t))
noexcept {
497 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)));
500 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5 >
501 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)
const)
noexcept {
502 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)));
505 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5 >
506 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)) {
507 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)));
510 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t >
511 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t)
const)
noexcept {
512 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6)));
515 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t >
516 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t))
noexcept {
517 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6)));
520 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t,
class a7_t >
521 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t)
const)
noexcept {
522 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7)));
525 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t,
class a7_t >
526 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t))
noexcept {
527 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7)));
530 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t,
class a7_t,
class a8_t >
531 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t)
const)
noexcept {
532 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8)));
535 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t,
class a7_t,
class a8_t >
536 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t))
noexcept {
537 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8)));
540 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t,
class a7_t,
class a8_t,
class a9_t >
541 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t, a9_t)
const)
noexcept {
542 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9)));
545 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t,
class a7_t,
class a8_t,
class a9_t >
546 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t, a9_t))
noexcept {
547 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9)));
550 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t,
class a7_t,
class a8_t,
class a9_t,
class a10_t >
551 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t, a9_t, a10_t)
const)
noexcept {
552 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9, std::placeholders::_10)));
555 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t,
class a7_t,
class a8_t,
class a9_t,
class a10_t >
556 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t, a9_t, a10_t))
noexcept {
557 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9, std::placeholders::_10)));
574 bool is_empty() const noexcept {
return data_->functions.size() == 0 && data_->no_arguments_functions.size() == 0;}
578 size_t size() const noexcept {
return data_->functions.size() + data_->no_arguments_functions.size();}
627 bool equals(
const object & obj)
const noexcept override {
return is < delegate > (obj) &&
equals(
static_cast < const delegate&
> (obj));}
632 if (data_->functions.size() !=
other.data_->functions.size() || data_->no_arguments_functions.size() !=
other.data_->no_arguments_functions.size())
635 for (
size_t i = 0;
i < data_->no_arguments_functions.size();
i++)
636 if (!are_equals(data_->no_arguments_functions[
i],
other.data_->no_arguments_functions[
i]))
639 for (
size_t i = 0;
i < data_->functions.size();
i++)
640 if (!are_equals(data_->functions[
i],
other.data_->functions[
i]))
659 result.data_->no_arguments_functions.push_back(function);
661 result.data_->functions.push_back(function);
674 result.data_->no_arguments_functions.push_back(function);
675 for (
const function_t& function :
b.data_->functions)
676 result.data_->functions.push_back(function);
687 std::for_each(value.data_->no_arguments_functions.begin(), value.data_->no_arguments_functions.end(), [&](
auto no_arguments_function) {
688 auto iterator = std::find_if(result.data_->no_arguments_functions.rbegin(), result.data_->no_arguments_functions.rend(), [&](auto item) {return are_equals(item, no_arguments_function);});
689 if (iterator != result.data_->no_arguments_functions.rend()) result.data_->no_arguments_functions.erase((iterator + 1).base());
692 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](
auto function) {
693 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
694 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
707 if (find(result.data_->no_arguments_functions.begin(), result.data_->no_arguments_functions.end(), function) != result.data_->no_arguments_functions.end()) {
708 for (
typename function_collection::reverse_iterator iterator = result.data_->no_arguments_functions.rbegin(); iterator != result.data_->no_arguments_functions.rend(); ++iterator) {
709 if (are_equals(*iterator, function))
710 result.data_->no_arguments_functions.erase((iterator + 1).base());
715 for (
const function_t& function : value.data_->functions) {
716 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
717 for (
typename function_collection::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
718 if (are_equals(*iterator, function))
719 result.data_->functions.erase((iterator + 1).base());
734 if (data_->no_arguments_functions.size() == 0 && data_->functions.size() == 0) {
735 if constexpr (std::is_void_v < result_t >)
return;
736 else if constexpr (std::is_reference_v < result_t >) {
737 using underlying_t = std::remove_reference_t < result_t >;
738 if constexpr (std::is_const_v < underlying_t >) {
739 static const underlying_t empty_value{};
742 static underlying_t empty_value{};
745 }
else return result_t{};
748 if (data_->no_arguments_functions.size()) {
749 for (
size_t i = 0;
i < data_->no_arguments_functions.size() - (data_->functions.size() == 0 ? 1 : 0);
i++) {
751 data_->no_arguments_functions[
i]();
754 if (data_->functions.size() == 0) {
756 return data_->no_arguments_functions.back()();
760 for (
size_t i = 0;
i < data_->functions.size() - 1;
i++) {
762 data_->functions[
i](arguments...);
765 return data_->functions.back()(arguments...);
770 template <
class type_t >
771 delegate& operator =(
const type_t& function)
noexcept {
772 data_->no_arguments_functions.clear();
773 data_->functions.clear();
774 data_->functions.push_back(function_t(function));
778 delegate& operator =(
const function_t& function)
noexcept {
779 data_->no_arguments_functions.clear();
780 data_->functions.clear();
781 data_->functions.push_back(function);
785 delegate& operator =(
const no_arguments_function_t& function)
noexcept {
786 data_->no_arguments_functions.clear();
787 data_->functions.clear();
788 data_->no_arguments_functions.push_back(function);
792 delegate operator +(
const delegate & other)
noexcept {
793 delegate result = *
this;
798 delegate operator +(
const no_arguments_function_t& function)
noexcept {
799 delegate result = *
this;
804 delegate operator +(
const function_t& function)
noexcept {
805 delegate result = *
this;
810 template <
class fn_t >
811 delegate operator +(fn_t function)
noexcept {
812 delegate result = *
this;
817 delegate & operator +=(
const delegate & delegate)
noexcept {
818 *
this = delegate::combine(*
this, delegate);
822 delegate & operator +=(
const no_arguments_function_t& function)
noexcept {
823 *
this = delegate::combine(*
this, delegate(function));
827 delegate & operator +=(
const function_t& function)
noexcept {
828 *
this = delegate::combine(*
this, delegate(function));
832 template <
class fn_t >
833 delegate & operator +=(fn_t function)
noexcept {
834 *
this = delegate::combine(*
this, delegate(function));
838 delegate operator -(
const delegate & other)
noexcept {
839 delegate result = *
this;
844 delegate operator -(
const no_arguments_function_t& function)
noexcept {
845 delegate result = *
this;
850 delegate operator -(
const function_t& function)
noexcept {
851 delegate result = *
this;
856 template <
class fn_t >
857 delegate operator -(fn_t function)
noexcept {
858 delegate result = *
this;
863 delegate & operator -=(
const delegate & delegate)
noexcept {
864 *
this = delegate::remove(*
this, delegate);
868 delegate & operator -=(
const no_arguments_function_t& function)
noexcept {
869 *
this = delegate::remove(*
this, delegate(function));
873 delegate & operator -=(
const function_t& function)
noexcept {
874 *
this = delegate::remove(*
this, delegate(function));
878 template <
class fn_t >
879 delegate & operator -=(fn_t function)
noexcept {
880 *
this = delegate::remove(*
this, delegate(function));
886 struct delegate_async_state;
888 static bool are_equals(
const std::function < result_t(arguments_t...) > & fct1,
const std::function < result_t(arguments_t...) > & fct2)
noexcept {
889 return fct1.target_type() == fct2.target_type() && (fct1.template target < result_t(*)(arguments_t...) > () == fct2.template target < result_t(*)(arguments_t...)>() || *fct1.template target<result_t(*)(arguments_t...) > () == *fct2.template target < result_t(*)(arguments_t...) > ());
892 static bool are_equals(
const std::function < result_t() > & fct1,
const std::function < result_t() > & fct2)
noexcept {
893 return fct1.target_type() == fct2.target_type() && (fct1.template target < result_t(*)() > () == fct2.template target < result_t(*)()>() || *fct1.template target<result_t(*)() > () == *fct2.template target < result_t(*)() > ());
896 static typename no_arguments_function_collection::const_iterator find(
typename no_arguments_function_collection::const_iterator begin,
typename no_arguments_function_collection::const_iterator end,
const no_arguments_function_t& function)
noexcept {
897 auto iterator = std::find_if(begin, end, [&](
auto item) {
return are_equals(item, function);});
898 if (iterator != end)
return iterator;
902 static typename function_collection::const_iterator find(
typename function_collection::const_iterator begin,
typename function_collection::const_iterator end,
const function_t& function)
noexcept {
903 auto iterator = std::find_if(begin, end, [&](
auto item) {
return are_equals(item, function);});
904 if (iterator != end)
return iterator;