@@ -344,6 +344,15 @@ class TaskRunner : public std::enable_shared_from_this<TaskRunner>
344
344
std::chrono::milliseconds delay);
345
345
346
346
private:
347
+ /* *
348
+ * Container to wrap around a generic callable type to allow perfect forwarding into lambdas.
349
+ */
350
+ template <typename TaskType>
351
+ struct TaskHolder
352
+ {
353
+ TaskType m_task;
354
+ };
355
+
347
356
/* *
348
357
* Wrap a task in a generic lambda to be agnostic to the return type of the task.
349
358
*
@@ -523,7 +532,7 @@ class SequencedTaskRunner : public TaskRunner
523
532
template <typename TaskType>
524
533
bool TaskRunner::post_task (TaskLocation &&location, TaskType &&task)
525
534
{
526
- return post_task_internal (std::move (location), wrap_task (std::move (task)));
535
+ return post_task_internal (std::move (location), wrap_task (std::forward<TaskType> (task)));
527
536
}
528
537
529
538
// ==================================================================================================
@@ -535,14 +544,16 @@ bool TaskRunner::post_task(
535
544
{
536
545
return post_task_internal (
537
546
std::move (location),
538
- wrap_task (std::move (task), std::move (weak_owner)));
547
+ wrap_task (std::forward<TaskType> (task), std::move (weak_owner)));
539
548
}
540
549
541
550
// ==================================================================================================
542
551
template <typename TaskType, typename ReplyType>
543
552
bool TaskRunner::post_task_with_reply (TaskLocation &&location, TaskType &&task, ReplyType reply)
544
553
{
545
- return post_task_internal (std::move (location), wrap_task (std::move (task), std::move (reply)));
554
+ return post_task_internal (
555
+ std::move (location),
556
+ wrap_task (std::forward<TaskType>(task), std::move (reply)));
546
557
}
547
558
548
559
// ==================================================================================================
@@ -555,7 +566,7 @@ bool TaskRunner::post_task_with_reply(
555
566
{
556
567
return post_task_internal (
557
568
std::move (location),
558
- wrap_task (std::move (task), std::move (reply), std::move (weak_owner)));
569
+ wrap_task (std::forward<TaskType> (task), std::move (reply), std::move (weak_owner)));
559
570
}
560
571
561
572
// ==================================================================================================
@@ -567,7 +578,7 @@ bool TaskRunner::post_task_with_delay(
567
578
{
568
579
return post_task_to_task_manager_with_delay (
569
580
std::move (location),
570
- wrap_task (std::move (task)),
581
+ wrap_task (std::forward<TaskType> (task)),
571
582
delay);
572
583
}
573
584
@@ -581,7 +592,7 @@ bool TaskRunner::post_task_with_delay(
581
592
{
582
593
return post_task_to_task_manager_with_delay (
583
594
std::move (location),
584
- wrap_task (std::move (task), std::move (weak_owner)),
595
+ wrap_task (std::forward<TaskType> (task), std::move (weak_owner)),
585
596
delay);
586
597
}
587
598
@@ -595,7 +606,7 @@ bool TaskRunner::post_task_with_delay_and_reply(
595
606
{
596
607
return post_task_to_task_manager_with_delay (
597
608
std::move (location),
598
- wrap_task (std::move (task), std::move (reply)),
609
+ wrap_task (std::forward<TaskType> (task), std::move (reply)),
599
610
delay);
600
611
}
601
612
@@ -610,7 +621,7 @@ bool TaskRunner::post_task_with_delay_and_reply(
610
621
{
611
622
return post_task_to_task_manager_with_delay (
612
623
std::move (location),
613
- wrap_task (std::move (task), std::move (reply), std::move (weak_owner)),
624
+ wrap_task (std::forward<TaskType> (task), std::move (reply), std::move (weak_owner)),
614
625
delay);
615
626
}
616
627
@@ -620,9 +631,11 @@ Task TaskRunner::wrap_task(TaskType &&task)
620
631
{
621
632
static_assert (std::is_invocable_v<TaskType>, " Task must be invocable without any arguments" );
622
633
623
- return [task = std::move (task)](TaskRunner *, TaskLocation) mutable
634
+ TaskHolder<TaskType> holder {std::forward<TaskType>(task)};
635
+
636
+ return [holder = std::move (holder)](TaskRunner *, TaskLocation) mutable
624
637
{
625
- FLY_UNUSED (std::move (task)( ));
638
+ FLY_UNUSED (std::invoke ( std:: move (holder. m_task ) ));
626
639
};
627
640
}
628
641
@@ -636,14 +649,14 @@ Task TaskRunner::wrap_task(TaskType &&task, std::weak_ptr<OwnerType> weak_owner)
636
649
std::is_invocable_v<TaskType, StrongOwnerType>,
637
650
" Task must be invocable with only a strong pointer to its owner" );
638
651
639
- return [task = std::move (task),
652
+ TaskHolder<TaskType> holder {std::forward<TaskType>(task)};
653
+
654
+ return [holder = std::move (holder),
640
655
weak_owner = std::move (weak_owner)](TaskRunner *, TaskLocation) mutable
641
656
{
642
- StrongOwnerType owner = weak_owner.lock ();
643
-
644
- if (owner)
657
+ if (StrongOwnerType owner = weak_owner.lock (); owner)
645
658
{
646
- FLY_UNUSED (std::move (task)( std::move (owner)));
659
+ FLY_UNUSED (std::invoke ( std:: move (holder. m_task ), std::move (owner)));
647
660
}
648
661
};
649
662
}
@@ -664,18 +677,25 @@ Task TaskRunner::wrap_task(TaskType &&task, ReplyType &&reply)
664
677
" that type, or the task must return void and the reply must be invocable without any "
665
678
" arguments" );
666
679
667
- return [task = std::move (task),
668
- reply = std::move (reply)](TaskRunner *runner, TaskLocation location) mutable
680
+ TaskHolder<TaskType> task_holder {std::forward<TaskType>(task)};
681
+ TaskHolder<ReplyType> reply_holder {std::forward<ReplyType>(reply)};
682
+
683
+ return
684
+ [task_holder = std::move (task_holder),
685
+ reply_holder = std::move (reply_holder)](TaskRunner *runner, TaskLocation location) mutable
669
686
{
670
687
if constexpr (s_result_is_void)
671
688
{
672
- std::move (task)( );
673
- runner->post_task (std::move (location), std::move (reply ));
689
+ std::invoke ( std:: move (task_holder. m_task ) );
690
+ runner->post_task (std::move (location), std::move (reply_holder. m_task ));
674
691
}
675
692
else
676
693
{
677
- auto result = std::move (task)();
678
- runner->post_task (std::move (location), std::bind (std::move (reply), std::move (result)));
694
+ auto result = std::invoke (std::move (task_holder.m_task ));
695
+
696
+ runner->post_task (
697
+ std::move (location),
698
+ std::bind (std::move (reply_holder.m_task ), std::move (result)));
679
699
}
680
700
};
681
701
}
@@ -700,29 +720,36 @@ Task TaskRunner::wrap_task(TaskType &&task, ReplyType &&reply, std::weak_ptr<Own
700
720
" type and a strong pointer to its owner, or the task must return void and the reply must "
701
721
" be invocable with only a strong pointer to its owner" );
702
722
703
- return [task = std::move (task),
704
- reply = std::move (reply),
723
+ TaskHolder<TaskType> task_holder {std::forward<TaskType>(task)};
724
+ TaskHolder<ReplyType> reply_holder {std::forward<ReplyType>(reply)};
725
+
726
+ return [task_holder = std::move (task_holder),
727
+ reply_holder = std::move (reply_holder),
705
728
weak_owner = std::move (weak_owner)](TaskRunner *runner, TaskLocation location) mutable
706
729
{
707
- StrongOwnerType owner = weak_owner.lock ();
708
- if (!owner)
709
- {
710
- return ;
711
- }
712
-
713
- if constexpr (s_result_is_void)
730
+ if (StrongOwnerType owner = weak_owner.lock (); owner)
714
731
{
715
- std::move (task)(std::move (owner));
716
- runner->post_task (std::move (location), std::move (reply), std::move (weak_owner));
717
- }
718
- else
719
- {
720
- auto result = std::move (task)(std::move (owner));
721
-
722
- runner->post_task (
723
- std::move (location),
724
- std::bind (std::move (reply), std::move (result), std::placeholders::_1),
725
- std::move (weak_owner));
732
+ if constexpr (s_result_is_void)
733
+ {
734
+ std::invoke (std::move (task_holder.m_task ), std::move (owner));
735
+
736
+ runner->post_task (
737
+ std::move (location),
738
+ std::move (reply_holder.m_task ),
739
+ std::move (weak_owner));
740
+ }
741
+ else
742
+ {
743
+ auto result = std::invoke (std::move (task_holder.m_task ), std::move (owner));
744
+
745
+ runner->post_task (
746
+ std::move (location),
747
+ std::bind (
748
+ std::move (reply_holder.m_task ),
749
+ std::move (result),
750
+ std::placeholders::_1),
751
+ std::move (weak_owner));
752
+ }
726
753
}
727
754
};
728
755
}
0 commit comments