Skip to content

Commit d11a670

Browse files
committed
Add more Callback tests
1 parent f87b323 commit d11a670

File tree

1 file changed

+196
-13
lines changed

1 file changed

+196
-13
lines changed

TESTS/mbed_functional/callback/main.cpp

Lines changed: 196 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,27 @@
1717
#include "greentea-client/test_env.h"
1818
#include "unity.h"
1919
#include "utest.h"
20+
#include <mstd_functional>
2021

2122
using 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
2543
template <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

534556
template <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
691870
utest::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

Comments
 (0)