18
18
#include " greentea-client/test_env.h"
19
19
#include " unity.h"
20
20
#include " utest.h"
21
+ #include < mstd_functional>
21
22
22
23
using namespace utest ::v1;
23
24
25
+ template <typename T>
26
+ using func0_type = T();
27
+
28
+ template <typename T>
29
+ using func1_type = T(T);
30
+
31
+ template <typename T>
32
+ using func2_type = T(T, T);
33
+
34
+ template <typename T>
35
+ using func3_type = T(T, T, T);
36
+
37
+ template <typename T>
38
+ using func4_type = T(T, T, T, T);
39
+
40
+ template <typename T>
41
+ using func5_type = T(T, T, T, T, T);
24
42
25
43
// static functions
26
44
template <typename T>
@@ -523,13 +541,17 @@ void test_dispatch0()
523
541
Verifier<T>::verify0 (&const_volatile_void_func0<T>, (const volatile Thing<T> *)&thing);
524
542
Verifier<T>::verify0 (callback (static_func0<T>));
525
543
526
- Callback<T ()> cb (static_func0);
544
+ Callback<T ()> cb (static_func0<T> );
527
545
Verifier<T>::verify0 (cb);
528
- cb = static_func0;
546
+ TEST_ASSERT_TRUE (cb);
547
+ func0_type<T> *p = nullptr ;
548
+ cb = p;
549
+ TEST_ASSERT_FALSE (cb);
550
+ cb = static_func0<T>;
529
551
Verifier<T>::verify0 (cb);
530
552
cb = {&bound_func0<T>, &thing};
531
553
Verifier<T>::verify0 (&cb, &Callback<T ()>::call);
532
- Verifier<T>::verify0 (&Callback<T ()>::thunk, ( void *) &cb);
554
+ Verifier<T>::verify0 (&Callback<T ()>::thunk, &cb);
533
555
}
534
556
535
557
template <typename T>
@@ -554,9 +576,13 @@ void test_dispatch1()
554
576
Verifier<T>::verify1 (&const_volatile_void_func1<T>, (const volatile Thing<T> *)&thing);
555
577
Verifier<T>::verify1 (callback (static_func1<T>));
556
578
557
- Callback<T (T)> cb (static_func1);
579
+ Callback<T (T)> cb (static_func1<T> );
558
580
Verifier<T>::verify1 (cb);
559
- cb = static_func1;
581
+ TEST_ASSERT_TRUE (cb);
582
+ func1_type<T> *p = nullptr ;
583
+ cb = p;
584
+ TEST_ASSERT_FALSE (cb);
585
+ cb = static_func1<T>;
560
586
Verifier<T>::verify1 (cb);
561
587
cb = {&bound_func1<T>, &thing};
562
588
Verifier<T>::verify1 (&cb, &Callback<T (T)>::call);
@@ -585,9 +611,13 @@ void test_dispatch2()
585
611
Verifier<T>::verify2 (&const_volatile_void_func2<T>, (const volatile Thing<T> *)&thing);
586
612
Verifier<T>::verify2 (callback (static_func2<T>));
587
613
588
- Callback<T (T, T)> cb (static_func2);
614
+ Callback<T (T, T)> cb (static_func2<T> );
589
615
Verifier<T>::verify2 (cb);
590
- cb = static_func2;
616
+ TEST_ASSERT_TRUE (cb);
617
+ func2_type<T> *p = nullptr ;
618
+ cb = p;
619
+ TEST_ASSERT_FALSE (cb);
620
+ cb = static_func2<T>;
591
621
Verifier<T>::verify2 (cb);
592
622
cb = {&bound_func2<T>, &thing};
593
623
Verifier<T>::verify2 (&cb, &Callback<T (T, T)>::call);
@@ -616,9 +646,13 @@ void test_dispatch3()
616
646
Verifier<T>::verify3 (&const_volatile_void_func3<T>, (const volatile Thing<T> *)&thing);
617
647
Verifier<T>::verify3 (callback (static_func3<T>));
618
648
619
- Callback<T (T, T, T)> cb (static_func3);
649
+ Callback<T (T, T, T)> cb (static_func3<T> );
620
650
Verifier<T>::verify3 (cb);
621
- cb = static_func3;
651
+ TEST_ASSERT_TRUE (cb);
652
+ func3_type<T> *p = nullptr ;
653
+ cb = p;
654
+ TEST_ASSERT_FALSE (cb);
655
+ cb = static_func3<T>;
622
656
Verifier<T>::verify3 (cb);
623
657
cb = {&bound_func3<T>, &thing};
624
658
Verifier<T>::verify3 (&cb, &Callback<T (T, T, T)>::call);
@@ -647,9 +681,13 @@ void test_dispatch4()
647
681
Verifier<T>::verify4 (&const_volatile_void_func4<T>, (const volatile Thing<T> *)&thing);
648
682
Verifier<T>::verify4 (callback (static_func4<T>));
649
683
650
- Callback<T (T, T, T, T)> cb (static_func4);
684
+ Callback<T (T, T, T, T)> cb (static_func4<T> );
651
685
Verifier<T>::verify4 (cb);
652
- cb = static_func4;
686
+ TEST_ASSERT_TRUE (cb);
687
+ func4_type<T> *p = nullptr ;
688
+ cb = p;
689
+ TEST_ASSERT_FALSE (cb);
690
+ cb = static_func4<T>;
653
691
Verifier<T>::verify4 (cb);
654
692
cb = {&bound_func4<T>, &thing};
655
693
Verifier<T>::verify4 (&cb, &Callback<T (T, T, T, T)>::call);
@@ -678,15 +716,159 @@ void test_dispatch5()
678
716
Verifier<T>::verify5 (&const_volatile_void_func5<T>, (const volatile Thing<T> *)&thing);
679
717
Verifier<T>::verify5 (callback (static_func5<T>));
680
718
681
- Callback<T (T, T, T, T, T)> cb (static_func5);
719
+ Callback<T (T, T, T, T, T)> cb (static_func5<T> );
682
720
Verifier<T>::verify5 (cb);
683
- cb = static_func5;
721
+ TEST_ASSERT_TRUE (cb);
722
+ func5_type<T> *p = nullptr ;
723
+ cb = p;
724
+ TEST_ASSERT_FALSE (cb);
725
+ cb = static_func5<T>;
684
726
Verifier<T>::verify5 (cb);
685
727
cb = {&bound_func5<T>, &thing};
686
728
Verifier<T>::verify5 (&cb, &Callback<T (T, T, T, T, T)>::call);
729
+ #if 0
687
730
Verifier<T>::verify5(&Callback<T(T, T, T, T, T)>::thunk, (void *)&cb);
731
+ #endif
732
+ }
733
+
734
+ #include < mstd_functional>
735
+
736
+ struct TrivialFunctionObject {
737
+ TrivialFunctionObject (int n) : val(n)
738
+ {
739
+ }
740
+
741
+ int operator ()(int x) const
742
+ {
743
+ return x + val;
744
+ }
745
+ private:
746
+ int val;
747
+ };
748
+
749
+ /* Exact count of copy, construction and destruction may vary depending on
750
+ * copy elision by compiler, but the derived live count can be relied upon.
751
+ */
752
+ static int construct_count;
753
+ static int destruct_count;
754
+ static int copy_count;
755
+
756
+ static int live_count ()
757
+ {
758
+ return construct_count - destruct_count;
688
759
}
689
760
761
+ struct FunctionObject {
762
+ FunctionObject (int n) : val(n)
763
+ {
764
+ construct_count++;
765
+ }
766
+
767
+ FunctionObject (const FunctionObject &other) : val(other.val)
768
+ {
769
+ construct_count++;
770
+ copy_count++;
771
+ }
772
+
773
+ ~FunctionObject ()
774
+ {
775
+ destruct_count++;
776
+ destroyed = true ;
777
+ }
778
+
779
+ int operator ()(int x) const
780
+ {
781
+ return destroyed ? -1000 : x + val;
782
+ }
783
+ private:
784
+ const int val;
785
+ bool destroyed = false ;
786
+ };
787
+
788
+ void test_trivial ()
789
+ {
790
+ TrivialFunctionObject fn (1 );
791
+ TEST_ASSERT_EQUAL (2 , fn (1 ));
792
+ Callback<int (int )> cb (fn);
793
+ TEST_ASSERT_TRUE (cb);
794
+ TEST_ASSERT_EQUAL (2 , cb (1 ));
795
+ fn = 5 ;
796
+ TEST_ASSERT_EQUAL (6 , fn (1 ));
797
+ TEST_ASSERT_EQUAL (2 , cb (1 ));
798
+ cb = std::ref (fn);
799
+ fn = 10 ;
800
+ TEST_ASSERT_EQUAL (11 , fn (1 ));
801
+ TEST_ASSERT_EQUAL (11 , cb (1 ));
802
+ cb = TrivialFunctionObject (3 );
803
+ TEST_ASSERT_EQUAL (7 , cb (4 ));
804
+ cb = nullptr ;
805
+ TEST_ASSERT_FALSE (cb);
806
+ cb = TrivialFunctionObject (7 );
807
+ Callback<int (int )> cb2 (cb);
808
+ TEST_ASSERT_EQUAL (8 , cb (1 ));
809
+ TEST_ASSERT_EQUAL (9 , cb2 (2 ));
810
+ cb2 = cb;
811
+ TEST_ASSERT_EQUAL (6 , cb2 (-1 ));
812
+ cb = cb;
813
+ TEST_ASSERT_EQUAL (8 , cb (1 ));
814
+ cb = std::negate<int >();
815
+ TEST_ASSERT_EQUAL (-4 , cb (4 ));
816
+ cb = [](int x) {
817
+ return x - 7 ;
818
+ };
819
+ TEST_ASSERT_EQUAL (1 , cb (8 ));
820
+ cb = cb2 = nullptr ;
821
+ TEST_ASSERT_FALSE (cb);
822
+ }
823
+
824
+ #if MBED_CONF_PLATFORM_CALLBACK_NONTRIVIAL
825
+ void test_nontrivial ()
826
+ {
827
+ {
828
+ FunctionObject fn (1 );
829
+ TEST_ASSERT_EQUAL (1 , construct_count);
830
+ TEST_ASSERT_EQUAL (0 , destruct_count);
831
+ TEST_ASSERT_EQUAL (2 , fn (1 ));
832
+ Callback<int (int )> cb (fn);
833
+ TEST_ASSERT_TRUE (cb);
834
+ TEST_ASSERT_EQUAL (2 , live_count ());
835
+ TEST_ASSERT_EQUAL (2 , cb (1 ));
836
+ cb = std::ref (fn);
837
+ TEST_ASSERT_EQUAL (1 , live_count ());
838
+ TEST_ASSERT_EQUAL (5 , cb (4 ));
839
+ cb = FunctionObject (3 );
840
+ TEST_ASSERT_EQUAL (2 , live_count ());
841
+ TEST_ASSERT_EQUAL (7 , cb (4 ));
842
+ cb = nullptr ;
843
+ TEST_ASSERT_FALSE (cb);
844
+ TEST_ASSERT_EQUAL (1 , live_count ());
845
+ cb = FunctionObject (7 );
846
+ TEST_ASSERT_EQUAL (2 , live_count ());
847
+ int old_copy_count = copy_count;
848
+ Callback<int (int )> cb2 (cb);
849
+ TEST_ASSERT_EQUAL (old_copy_count + 1 , copy_count);
850
+ TEST_ASSERT_EQUAL (3 , live_count ());
851
+ TEST_ASSERT_EQUAL (8 , cb (1 ));
852
+ TEST_ASSERT_EQUAL (9 , cb2 (2 ));
853
+ old_copy_count = copy_count;
854
+ cb2 = cb;
855
+ TEST_ASSERT_EQUAL (old_copy_count + 1 , copy_count);
856
+ TEST_ASSERT_EQUAL (3 , live_count ());
857
+ TEST_ASSERT_EQUAL (6 , cb2 (-1 ));
858
+ int old_construct_count = construct_count;
859
+ old_copy_count = copy_count;
860
+ cb = cb;
861
+ TEST_ASSERT_EQUAL (3 , live_count ());
862
+ TEST_ASSERT_EQUAL (old_construct_count, construct_count);
863
+ TEST_ASSERT_EQUAL (old_copy_count, copy_count);
864
+ cb = cb2 = nullptr ;
865
+ TEST_ASSERT_FALSE (cb);
866
+ TEST_ASSERT_EQUAL (1 , live_count ());
867
+ }
868
+ TEST_ASSERT_EQUAL (0 , live_count ());
869
+ }
870
+ #endif
871
+
690
872
691
873
// Test setup
692
874
utest::v1::status_t test_setup (const size_t number_of_cases)
@@ -717,6 +899,10 @@ Case cases[] = {
717
899
Case (" Testing callbacks with 3 ints" , test_dispatch3<int >),
718
900
Case (" Testing callbacks with 4 ints" , test_dispatch4<int >),
719
901
Case (" Testing callbacks with 5 ints" , test_dispatch5<int >),
902
+ Case (" Testing trivial function object" , test_trivial),
903
+ #if MBED_CONF_PLATFORM_CALLBACK_NONTRIVIAL
904
+ Case (" Testing non-trivial function object" , test_nontrivial),
905
+ #endif
720
906
#endif
721
907
};
722
908
0 commit comments