Skip to content

Commit 6a178a9

Browse files
committed
Add more Callback tests
1 parent ae341cf commit 6a178a9

File tree

1 file changed

+199
-13
lines changed

1 file changed

+199
-13
lines changed

TESTS/mbed_functional/callback/main.cpp

Lines changed: 199 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,27 @@
1818
#include "greentea-client/test_env.h"
1919
#include "unity.h"
2020
#include "utest.h"
21+
#include <mstd_functional>
2122

2223
using namespace utest::v1;
2324

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);
2442

2543
// static functions
2644
template <typename T>
@@ -523,13 +541,17 @@ void test_dispatch0()
523541
Verifier<T>::verify0(&const_volatile_void_func0<T>, (const volatile Thing<T> *)&thing);
524542
Verifier<T>::verify0(callback(static_func0<T>));
525543

526-
Callback<T()> cb(static_func0);
544+
Callback<T()> cb(static_func0<T>);
527545
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>;
529551
Verifier<T>::verify0(cb);
530552
cb = {&bound_func0<T>, &thing};
531553
Verifier<T>::verify0(&cb, &Callback<T()>::call);
532-
Verifier<T>::verify0(&Callback<T()>::thunk, (void *)&cb);
554+
Verifier<T>::verify0(&Callback<T()>::thunk, &cb);
533555
}
534556

535557
template <typename T>
@@ -554,9 +576,13 @@ void test_dispatch1()
554576
Verifier<T>::verify1(&const_volatile_void_func1<T>, (const volatile Thing<T> *)&thing);
555577
Verifier<T>::verify1(callback(static_func1<T>));
556578

557-
Callback<T(T)> cb(static_func1);
579+
Callback<T(T)> cb(static_func1<T>);
558580
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>;
560586
Verifier<T>::verify1(cb);
561587
cb = {&bound_func1<T>, &thing};
562588
Verifier<T>::verify1(&cb, &Callback<T(T)>::call);
@@ -585,9 +611,13 @@ void test_dispatch2()
585611
Verifier<T>::verify2(&const_volatile_void_func2<T>, (const volatile Thing<T> *)&thing);
586612
Verifier<T>::verify2(callback(static_func2<T>));
587613

588-
Callback<T(T, T)> cb(static_func2);
614+
Callback<T(T, T)> cb(static_func2<T>);
589615
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>;
591621
Verifier<T>::verify2(cb);
592622
cb = {&bound_func2<T>, &thing};
593623
Verifier<T>::verify2(&cb, &Callback<T(T, T)>::call);
@@ -616,9 +646,13 @@ void test_dispatch3()
616646
Verifier<T>::verify3(&const_volatile_void_func3<T>, (const volatile Thing<T> *)&thing);
617647
Verifier<T>::verify3(callback(static_func3<T>));
618648

619-
Callback<T(T, T, T)> cb(static_func3);
649+
Callback<T(T, T, T)> cb(static_func3<T>);
620650
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>;
622656
Verifier<T>::verify3(cb);
623657
cb = {&bound_func3<T>, &thing};
624658
Verifier<T>::verify3(&cb, &Callback<T(T, T, T)>::call);
@@ -647,9 +681,13 @@ void test_dispatch4()
647681
Verifier<T>::verify4(&const_volatile_void_func4<T>, (const volatile Thing<T> *)&thing);
648682
Verifier<T>::verify4(callback(static_func4<T>));
649683

650-
Callback<T(T, T, T, T)> cb(static_func4);
684+
Callback<T(T, T, T, T)> cb(static_func4<T>);
651685
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>;
653691
Verifier<T>::verify4(cb);
654692
cb = {&bound_func4<T>, &thing};
655693
Verifier<T>::verify4(&cb, &Callback<T(T, T, T, T)>::call);
@@ -678,15 +716,159 @@ void test_dispatch5()
678716
Verifier<T>::verify5(&const_volatile_void_func5<T>, (const volatile Thing<T> *)&thing);
679717
Verifier<T>::verify5(callback(static_func5<T>));
680718

681-
Callback<T(T, T, T, T, T)> cb(static_func5);
719+
Callback<T(T, T, T, T, T)> cb(static_func5<T>);
682720
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>;
684726
Verifier<T>::verify5(cb);
685727
cb = {&bound_func5<T>, &thing};
686728
Verifier<T>::verify5(&cb, &Callback<T(T, T, T, T, T)>::call);
729+
#if 0
687730
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;
688759
}
689760

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+
690872

691873
// Test setup
692874
utest::v1::status_t test_setup(const size_t number_of_cases)
@@ -717,6 +899,10 @@ Case cases[] = {
717899
Case("Testing callbacks with 3 ints", test_dispatch3<int>),
718900
Case("Testing callbacks with 4 ints", test_dispatch4<int>),
719901
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
720906
#endif
721907
};
722908

0 commit comments

Comments
 (0)