397 std::vector < std::function < result_t(arguments_t...)>>
functions;
406 bool completed_synchronously()
const noexcept override;
407 bool is_completed()
const noexcept override;
419 using function_t = std::function < result_t(arguments_t...) >;
443 delegate(
const no_arguments_function_t& function)
noexcept {data_->no_arguments_functions.push_back(function);}
449 template <
class object1_t,
class object2_t >
450 delegate(
const object1_t&
object, result_t(object2_t::*method)()
const) noexcept {
451 data_->functions.push_back(
function_t(std::bind(method,
const_cast < object1_t*
> (&
object))));
457 template <
class object1_t,
class object2_t >
458 delegate(
const object1_t&
object, result_t(object2_t::*method)()) noexcept {
459 data_->functions.push_back(
function_t(std::bind(method,
const_cast < object1_t*
> (&
object))));
464 template <
class object1_t,
class object2_t,
class a1_t >
465 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t)
const)
noexcept {
466 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1)));
469 template <
class object1_t,
class object2_t,
class a1_t >
470 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t))
noexcept {
471 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1)));
474 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t >
475 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t)
const)
noexcept {
476 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2)));
479 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t >
480 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t))
noexcept {
481 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2)));
484 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t >
485 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t)
const)
noexcept {
486 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
489 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t >
490 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t))
noexcept {
491 data_->functions.push_back(function_t(std::bind(method,
const_cast < object1_t*
> (&
object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
494 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t >
495 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t)
const) {
496 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)));
499 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t >
500 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t))
noexcept {
501 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)));
504 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5 >
505 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)
const)
noexcept {
506 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)));
509 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5 >
510 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)) {
511 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)));
514 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t >
515 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t)
const)
noexcept {
516 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)));
519 template <
class object1_t,
class object2_t,
class a1_t,
class a2_t,
class a3_t,
class a4_t,
class A5,
class a6_t >
520 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t))
noexcept {
521 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)));
524 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 >
525 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 {
526 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)));
529 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 >
530 delegate(
const object1_t&
object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t))
noexcept {
531 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)));
534 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 >
535 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 {
536 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)));
539 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 >
540 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 {
541 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)));
544 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 >
545 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 {
546 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)));
549 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 >
550 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 {
551 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)));
554 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 >
555 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 {
556 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)));
559 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 >
560 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 {
561 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)));
570 size_t count() const noexcept {
return data_->functions.size() + data_->no_arguments_functions.size();}
635 bool equals(
const object & obj)
const noexcept override {
return is < delegate > (obj) &&
equals(
static_cast < const delegate&
> (obj));}
640 if (data_->functions.size() !=
other.data_->functions.size() || data_->no_arguments_functions.size() !=
other.data_->no_arguments_functions.size())
643 for (
size_t i = 0;
i < data_->no_arguments_functions.size();
i++)
644 if (!are_equals(data_->no_arguments_functions[
i],
other.data_->no_arguments_functions[
i]))
647 for (
size_t i = 0;
i < data_->functions.size();
i++)
648 if (!are_equals(data_->functions[
i],
other.data_->functions[
i]))
667 result.data_->no_arguments_functions.push_back(function);
669 result.data_->functions.push_back(function);
682 result.data_->no_arguments_functions.push_back(function);
683 for (
const function_t& function :
b.data_->functions)
684 result.data_->functions.push_back(function);
695 std::for_each(value.data_->no_arguments_functions.begin(), value.data_->no_arguments_functions.end(), [&](
auto no_arguments_function) {
696 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);});
697 if (iterator != result.data_->no_arguments_functions.rend()) result.data_->no_arguments_functions.erase((iterator + 1).base());
700 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](
auto function) {
701 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
702 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
715 if (find(result.data_->no_arguments_functions.begin(), result.data_->no_arguments_functions.end(), function) != result.data_->no_arguments_functions.end()) {
716 for (
typename function_collection::reverse_iterator iterator = result.data_->no_arguments_functions.rbegin(); iterator != result.data_->no_arguments_functions.rend(); ++iterator) {
717 if (are_equals(*iterator, function))
718 result.data_->no_arguments_functions.erase((iterator + 1).base());
723 for (
const function_t& function : value.data_->functions) {
724 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
725 for (
typename function_collection::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
726 if (are_equals(*iterator, function))
727 result.data_->functions.erase((iterator + 1).base());
742 if (data_->no_arguments_functions.size() == 0 && data_->functions.size() == 0) {
743 if constexpr(std::is_void_v < result_t >)
return;
744 else if constexpr(std::is_reference_v < result_t >) {
745 using underlying_t = std::remove_reference_t < result_t >;
746 if constexpr(std::is_const_v < underlying_t >) {
747 static const underlying_t empty_value{};
750 static underlying_t empty_value{};
753 }
else return result_t{};
756 if (data_->no_arguments_functions.size()) {
757 for (
size_t i = 0;
i < data_->no_arguments_functions.size() - (data_->functions.size() == 0 ? 1 : 0);
i++) {
759 data_->no_arguments_functions[
i]();
762 if (data_->functions.size() == 0) {
764 return data_->no_arguments_functions.back()();
768 for (
size_t i = 0;
i < data_->functions.size() - 1;
i++) {
770 data_->functions[
i](arguments...);
773 return data_->functions.back()(arguments...);
778 template <
class type_t >
779 delegate& operator =(
const type_t& function)
noexcept {
780 data_->no_arguments_functions.clear();
781 data_->functions.clear();
782 data_->functions.push_back(function_t(function));
786 delegate& operator =(
const function_t& function)
noexcept {
787 data_->no_arguments_functions.clear();
788 data_->functions.clear();
789 data_->functions.push_back(function);
793 delegate& operator =(
const no_arguments_function_t& function)
noexcept {
794 data_->no_arguments_functions.clear();
795 data_->functions.clear();
796 data_->no_arguments_functions.push_back(function);
800 delegate operator +(
const delegate & other)
noexcept {
801 delegate result = *
this;
806 delegate operator +(
const no_arguments_function_t& function)
noexcept {
807 delegate result = *
this;
812 delegate operator +(
const function_t& function)
noexcept {
813 delegate result = *
this;
818 template <
class fn_t >
819 delegate operator +(fn_t function)
noexcept {
820 delegate result = *
this;
825 delegate& operator +=(
const delegate & delegate)
noexcept {
826 *
this = delegate::combine(*
this, delegate);
830 delegate& operator +=(
const no_arguments_function_t& function)
noexcept {
831 *
this = delegate::combine(*
this, delegate(function));
835 delegate& operator +=(
const function_t& function)
noexcept {
836 *
this = delegate::combine(*
this, delegate(function));
840 template <
class fn_t >
841 delegate& operator +=(fn_t function)
noexcept {
842 *
this = delegate::combine(*
this, delegate(function));
846 delegate operator -(
const delegate & other)
noexcept {
847 delegate result = *
this;
852 delegate operator -(
const no_arguments_function_t& function)
noexcept {
853 delegate result = *
this;
858 delegate operator -(
const function_t& function)
noexcept {
859 delegate result = *
this;
864 template <
class fn_t >
865 delegate operator -(fn_t function)
noexcept {
866 delegate result = *
this;
871 delegate& operator -=(
const delegate & delegate)
noexcept {
872 *
this = delegate::remove(*
this, delegate);
876 delegate& operator -=(
const no_arguments_function_t& function)
noexcept {
877 *
this = delegate::remove(*
this, delegate(function));
881 delegate& operator -=(
const function_t& function)
noexcept {
882 *
this = delegate::remove(*
this, delegate(function));
886 template <
class fn_t >
887 delegate& operator -=(fn_t function)
noexcept {
888 *
this = delegate::remove(*
this, delegate(function));
894 struct delegate_async_state;
896 static bool are_equals(
const std::function < result_t(arguments_t...) >& fct1,
const std::function < result_t(arguments_t...) >& fct2)
noexcept {
897 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...) > ());
900 static bool are_equals(
const std::function < result_t() >& fct1,
const std::function < result_t() >& fct2)
noexcept {
901 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(*)() > ());
904 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 {
905 auto iterator = std::find_if(begin, end, [&](
auto item) {
return are_equals(item, function);});
906 if (iterator != end)
return iterator;
910 static typename function_collection::const_iterator find(
typename function_collection::const_iterator begin,
typename function_collection::const_iterator end,
const function_t& function)
noexcept {
911 auto iterator = std::find_if(begin, end, [&](
auto item) {
return are_equals(item, function);});
912 if (iterator != end)
return iterator;