1717#include " greentea-client/test_env.h"
1818#include " unity.h"
1919#include " utest.h"
20+ #include < mstd_functional>
2021
2122using namespace utest ::v1;
2223
24+ template <typename T>
25+ using func0_type = T();
26+
27+ template <typename T>
28+ using func1_type = T(T);
29+
30+ template <typename T>
31+ using func2_type = T(T, T);
32+
33+ template <typename T>
34+ using func3_type = T(T, T, T);
35+
36+ template <typename T>
37+ using func4_type = T(T, T, T, T);
38+
39+ template <typename T>
40+ using func5_type = T(T, T, T, T, T);
2341
2442// static functions
2543template <typename T>
@@ -522,13 +540,17 @@ void test_dispatch0()
522540 Verifier<T>::verify0 (&const_volatile_void_func0<T>, (const volatile Thing<T> *)&thing);
523541 Verifier<T>::verify0 (callback (static_func0<T>));
524542
525- Callback<T ()> cb (static_func0);
543+ Callback<T ()> cb (static_func0<T> );
526544 Verifier<T>::verify0 (cb);
527- cb = static_func0;
545+ TEST_ASSERT_TRUE (cb);
546+ func0_type<T> *p = nullptr ;
547+ cb = p;
548+ TEST_ASSERT_FALSE (cb);
549+ cb = static_func0<T>;
528550 Verifier<T>::verify0 (cb);
529551 cb = {&bound_func0<T>, &thing};
530552 Verifier<T>::verify0 (&cb, &Callback<T ()>::call);
531- Verifier<T>::verify0 (&Callback<T ()>::thunk, ( void *) &cb);
553+ Verifier<T>::verify0 (&Callback<T ()>::thunk, &cb);
532554}
533555
534556template <typename T>
@@ -553,9 +575,13 @@ void test_dispatch1()
553575 Verifier<T>::verify1 (&const_volatile_void_func1<T>, (const volatile Thing<T> *)&thing);
554576 Verifier<T>::verify1 (callback (static_func1<T>));
555577
556- Callback<T (T)> cb (static_func1);
578+ Callback<T (T)> cb (static_func1<T> );
557579 Verifier<T>::verify1 (cb);
558- cb = static_func1;
580+ TEST_ASSERT_TRUE (cb);
581+ func1_type<T> *p = nullptr ;
582+ cb = p;
583+ TEST_ASSERT_FALSE (cb);
584+ cb = static_func1<T>;
559585 Verifier<T>::verify1 (cb);
560586 cb = {&bound_func1<T>, &thing};
561587 Verifier<T>::verify1 (&cb, &Callback<T (T)>::call);
@@ -584,9 +610,13 @@ void test_dispatch2()
584610 Verifier<T>::verify2 (&const_volatile_void_func2<T>, (const volatile Thing<T> *)&thing);
585611 Verifier<T>::verify2 (callback (static_func2<T>));
586612
587- Callback<T (T, T)> cb (static_func2);
613+ Callback<T (T, T)> cb (static_func2<T> );
588614 Verifier<T>::verify2 (cb);
589- cb = static_func2;
615+ TEST_ASSERT_TRUE (cb);
616+ func2_type<T> *p = nullptr ;
617+ cb = p;
618+ TEST_ASSERT_FALSE (cb);
619+ cb = static_func2<T>;
590620 Verifier<T>::verify2 (cb);
591621 cb = {&bound_func2<T>, &thing};
592622 Verifier<T>::verify2 (&cb, &Callback<T (T, T)>::call);
@@ -615,9 +645,13 @@ void test_dispatch3()
615645 Verifier<T>::verify3 (&const_volatile_void_func3<T>, (const volatile Thing<T> *)&thing);
616646 Verifier<T>::verify3 (callback (static_func3<T>));
617647
618- Callback<T (T, T, T)> cb (static_func3);
648+ Callback<T (T, T, T)> cb (static_func3<T> );
619649 Verifier<T>::verify3 (cb);
620- cb = static_func3;
650+ TEST_ASSERT_TRUE (cb);
651+ func3_type<T> *p = nullptr ;
652+ cb = p;
653+ TEST_ASSERT_FALSE (cb);
654+ cb = static_func3<T>;
621655 Verifier<T>::verify3 (cb);
622656 cb = {&bound_func3<T>, &thing};
623657 Verifier<T>::verify3 (&cb, &Callback<T (T, T, T)>::call);
@@ -646,9 +680,13 @@ void test_dispatch4()
646680 Verifier<T>::verify4 (&const_volatile_void_func4<T>, (const volatile Thing<T> *)&thing);
647681 Verifier<T>::verify4 (callback (static_func4<T>));
648682
649- Callback<T (T, T, T, T)> cb (static_func4);
683+ Callback<T (T, T, T, T)> cb (static_func4<T> );
650684 Verifier<T>::verify4 (cb);
651- cb = static_func4;
685+ TEST_ASSERT_TRUE (cb);
686+ func4_type<T> *p = nullptr ;
687+ cb = p;
688+ TEST_ASSERT_FALSE (cb);
689+ cb = static_func4<T>;
652690 Verifier<T>::verify4 (cb);
653691 cb = {&bound_func4<T>, &thing};
654692 Verifier<T>::verify4 (&cb, &Callback<T (T, T, T, T)>::call);
@@ -677,15 +715,156 @@ void test_dispatch5()
677715 Verifier<T>::verify5 (&const_volatile_void_func5<T>, (const volatile Thing<T> *)&thing);
678716 Verifier<T>::verify5 (callback (static_func5<T>));
679717
680- Callback<T (T, T, T, T, T)> cb (static_func5);
718+ Callback<T (T, T, T, T, T)> cb (static_func5<T> );
681719 Verifier<T>::verify5 (cb);
682- cb = static_func5;
720+ TEST_ASSERT_TRUE (cb);
721+ func5_type<T> *p = nullptr ;
722+ cb = p;
723+ TEST_ASSERT_FALSE (cb);
724+ cb = static_func5<T>;
683725 Verifier<T>::verify5 (cb);
684726 cb = {&bound_func5<T>, &thing};
685727 Verifier<T>::verify5 (&cb, &Callback<T (T, T, T, T, T)>::call);
728+ #if 0
686729 Verifier<T>::verify5(&Callback<T(T, T, T, T, T)>::thunk, (void *)&cb);
730+ #endif
687731}
688732
733+ #include < mstd_functional>
734+
735+ struct TrivialFunctionObject {
736+ TrivialFunctionObject (int n) : val(n)
737+ {
738+ }
739+
740+ int operator ()(int x) const
741+ {
742+ return x + val;
743+ }
744+ private:
745+ int val;
746+ };
747+
748+ static int construct_count;
749+ static int destruct_count;
750+ static int copy_count;
751+
752+ static int live_count ()
753+ {
754+ return construct_count - destruct_count;
755+ }
756+
757+ struct FunctionObject {
758+ FunctionObject (int n) : val(n)
759+ {
760+ construct_count++;
761+ }
762+
763+ FunctionObject (const FunctionObject &other) : val(other.val)
764+ {
765+ construct_count++;
766+ copy_count++;
767+ }
768+
769+ ~FunctionObject ()
770+ {
771+ destruct_count++;
772+ destroyed = true ;
773+ }
774+
775+ int operator ()(int x) const
776+ {
777+ return destroyed ? -1000 : x + val;
778+ }
779+ private:
780+ const int val;
781+ bool destroyed = false ;
782+ };
783+
784+ void test_trivial ()
785+ {
786+ TrivialFunctionObject fn (1 );
787+ TEST_ASSERT_EQUAL (2 , fn (1 ));
788+ Callback<int (int )> cb (fn);
789+ TEST_ASSERT_TRUE (cb);
790+ TEST_ASSERT_EQUAL (2 , cb (1 ));
791+ fn = 5 ;
792+ TEST_ASSERT_EQUAL (6 , fn (1 ));
793+ TEST_ASSERT_EQUAL (2 , cb (1 ));
794+ cb = std::ref (fn);
795+ fn = 10 ;
796+ TEST_ASSERT_EQUAL (11 , fn (1 ));
797+ TEST_ASSERT_EQUAL (11 , cb (1 ));
798+ cb = TrivialFunctionObject (3 );
799+ TEST_ASSERT_EQUAL (7 , cb (4 ));
800+ cb = nullptr ;
801+ TEST_ASSERT_FALSE (cb);
802+ cb = TrivialFunctionObject (7 );
803+ Callback<int (int )> cb2 (cb);
804+ TEST_ASSERT_EQUAL (8 , cb (1 ));
805+ TEST_ASSERT_EQUAL (9 , cb2 (2 ));
806+ cb2 = cb;
807+ TEST_ASSERT_EQUAL (6 , cb2 (-1 ));
808+ cb = cb;
809+ TEST_ASSERT_EQUAL (8 , cb (1 ));
810+ cb = std::negate<int >();
811+ TEST_ASSERT_EQUAL (-4 , cb (4 ));
812+ cb = [](int x) {
813+ return x - 7 ;
814+ };
815+ TEST_ASSERT_EQUAL (1 , cb (8 ));
816+ cb = cb2 = nullptr ;
817+ TEST_ASSERT_FALSE (cb);
818+ }
819+
820+ #if MBED_CONF_PLATFORM_CALLBACK_NONTRIVIAL
821+ void test_nontrivial ()
822+ {
823+ {
824+ FunctionObject fn (1 );
825+ TEST_ASSERT_EQUAL (1 , construct_count);
826+ TEST_ASSERT_EQUAL (0 , destruct_count);
827+ TEST_ASSERT_EQUAL (2 , fn (1 ));
828+ Callback<int (int )> cb (fn);
829+ TEST_ASSERT_TRUE (cb);
830+ TEST_ASSERT_EQUAL (2 , live_count ());
831+ TEST_ASSERT_EQUAL (2 , cb (1 ));
832+ cb = std::ref (fn);
833+ TEST_ASSERT_EQUAL (1 , live_count ());
834+ TEST_ASSERT_EQUAL (5 , cb (4 ));
835+ cb = FunctionObject (3 );
836+ TEST_ASSERT_EQUAL (2 , live_count ());
837+ TEST_ASSERT_EQUAL (7 , cb (4 ));
838+ cb = nullptr ;
839+ TEST_ASSERT_FALSE (cb);
840+ TEST_ASSERT_EQUAL (1 , live_count ());
841+ cb = FunctionObject (7 );
842+ TEST_ASSERT_EQUAL (2 , live_count ());
843+ int old_copy_count = copy_count;
844+ Callback<int (int )> cb2 (cb);
845+ TEST_ASSERT_EQUAL (old_copy_count + 1 , copy_count);
846+ TEST_ASSERT_EQUAL (3 , live_count ());
847+ TEST_ASSERT_EQUAL (8 , cb (1 ));
848+ TEST_ASSERT_EQUAL (9 , cb2 (2 ));
849+ old_copy_count = copy_count;
850+ cb2 = cb;
851+ TEST_ASSERT_EQUAL (old_copy_count + 1 , copy_count);
852+ TEST_ASSERT_EQUAL (3 , live_count ());
853+ TEST_ASSERT_EQUAL (6 , cb2 (-1 ));
854+ int old_construct_count = construct_count;
855+ old_copy_count = copy_count;
856+ cb = cb;
857+ TEST_ASSERT_EQUAL (3 , live_count ());
858+ TEST_ASSERT_EQUAL (old_construct_count, construct_count);
859+ TEST_ASSERT_EQUAL (old_copy_count, copy_count);
860+ cb = cb2 = nullptr ;
861+ TEST_ASSERT_FALSE (cb);
862+ TEST_ASSERT_EQUAL (1 , live_count ());
863+ }
864+ TEST_ASSERT_EQUAL (0 , live_count ());
865+ }
866+ #endif
867+
689868
690869// Test setup
691870utest::v1::status_t test_setup (const size_t number_of_cases)
@@ -716,6 +895,10 @@ Case cases[] = {
716895 Case (" Testing callbacks with 3 ints" , test_dispatch3<int >),
717896 Case (" Testing callbacks with 4 ints" , test_dispatch4<int >),
718897 Case (" Testing callbacks with 5 ints" , test_dispatch5<int >),
898+ Case (" Testing trivial function object" , test_trivial),
899+ #if MBED_CONF_PLATFORM_CALLBACK_NONTRIVIAL
900+ Case (" Testing non-trivial function object" , test_nontrivial),
901+ #endif
719902#endif
720903};
721904
0 commit comments