17
17
#include " greentea-client/test_env.h"
18
18
#include " unity.h"
19
19
#include " utest.h"
20
+ #include < mstd_functional>
20
21
21
22
using namespace utest ::v1;
22
23
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);
23
41
24
42
// static functions
25
43
template <typename T>
@@ -522,13 +540,17 @@ void test_dispatch0()
522
540
Verifier<T>::verify0 (&const_volatile_void_func0<T>, (const volatile Thing<T> *)&thing);
523
541
Verifier<T>::verify0 (callback (static_func0<T>));
524
542
525
- Callback<T ()> cb (static_func0);
543
+ Callback<T ()> cb (static_func0<T> );
526
544
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>;
528
550
Verifier<T>::verify0 (cb);
529
551
cb = {&bound_func0<T>, &thing};
530
552
Verifier<T>::verify0 (&cb, &Callback<T ()>::call);
531
- Verifier<T>::verify0 (&Callback<T ()>::thunk, ( void *) &cb);
553
+ Verifier<T>::verify0 (&Callback<T ()>::thunk, &cb);
532
554
}
533
555
534
556
template <typename T>
@@ -553,9 +575,13 @@ void test_dispatch1()
553
575
Verifier<T>::verify1 (&const_volatile_void_func1<T>, (const volatile Thing<T> *)&thing);
554
576
Verifier<T>::verify1 (callback (static_func1<T>));
555
577
556
- Callback<T (T)> cb (static_func1);
578
+ Callback<T (T)> cb (static_func1<T> );
557
579
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>;
559
585
Verifier<T>::verify1 (cb);
560
586
cb = {&bound_func1<T>, &thing};
561
587
Verifier<T>::verify1 (&cb, &Callback<T (T)>::call);
@@ -584,9 +610,13 @@ void test_dispatch2()
584
610
Verifier<T>::verify2 (&const_volatile_void_func2<T>, (const volatile Thing<T> *)&thing);
585
611
Verifier<T>::verify2 (callback (static_func2<T>));
586
612
587
- Callback<T (T, T)> cb (static_func2);
613
+ Callback<T (T, T)> cb (static_func2<T> );
588
614
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>;
590
620
Verifier<T>::verify2 (cb);
591
621
cb = {&bound_func2<T>, &thing};
592
622
Verifier<T>::verify2 (&cb, &Callback<T (T, T)>::call);
@@ -615,9 +645,13 @@ void test_dispatch3()
615
645
Verifier<T>::verify3 (&const_volatile_void_func3<T>, (const volatile Thing<T> *)&thing);
616
646
Verifier<T>::verify3 (callback (static_func3<T>));
617
647
618
- Callback<T (T, T, T)> cb (static_func3);
648
+ Callback<T (T, T, T)> cb (static_func3<T> );
619
649
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>;
621
655
Verifier<T>::verify3 (cb);
622
656
cb = {&bound_func3<T>, &thing};
623
657
Verifier<T>::verify3 (&cb, &Callback<T (T, T, T)>::call);
@@ -646,9 +680,13 @@ void test_dispatch4()
646
680
Verifier<T>::verify4 (&const_volatile_void_func4<T>, (const volatile Thing<T> *)&thing);
647
681
Verifier<T>::verify4 (callback (static_func4<T>));
648
682
649
- Callback<T (T, T, T, T)> cb (static_func4);
683
+ Callback<T (T, T, T, T)> cb (static_func4<T> );
650
684
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>;
652
690
Verifier<T>::verify4 (cb);
653
691
cb = {&bound_func4<T>, &thing};
654
692
Verifier<T>::verify4 (&cb, &Callback<T (T, T, T, T)>::call);
@@ -677,15 +715,156 @@ void test_dispatch5()
677
715
Verifier<T>::verify5 (&const_volatile_void_func5<T>, (const volatile Thing<T> *)&thing);
678
716
Verifier<T>::verify5 (callback (static_func5<T>));
679
717
680
- Callback<T (T, T, T, T, T)> cb (static_func5);
718
+ Callback<T (T, T, T, T, T)> cb (static_func5<T> );
681
719
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>;
683
725
Verifier<T>::verify5 (cb);
684
726
cb = {&bound_func5<T>, &thing};
685
727
Verifier<T>::verify5 (&cb, &Callback<T (T, T, T, T, T)>::call);
728
+ #if 0
686
729
Verifier<T>::verify5(&Callback<T(T, T, T, T, T)>::thunk, (void *)&cb);
730
+ #endif
687
731
}
688
732
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
+
689
868
690
869
// Test setup
691
870
utest::v1::status_t test_setup (const size_t number_of_cases)
@@ -716,6 +895,10 @@ Case cases[] = {
716
895
Case (" Testing callbacks with 3 ints" , test_dispatch3<int >),
717
896
Case (" Testing callbacks with 4 ints" , test_dispatch4<int >),
718
897
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
719
902
#endif
720
903
};
721
904
0 commit comments