From e554d30bf6df4d930a489fd55c09504f39053437 Mon Sep 17 00:00:00 2001 From: Erki Date: Sun, 26 Jun 2022 17:53:40 +0300 Subject: [PATCH] Utility: add the ability to generate static functions from IFunction --- Peripherals/Inc/peripherals_utility.hpp | 4 --- Tests/function.cpp | 47 +++++++++++++++++++++++++ Utility/Inc/utility_function.hpp | 8 +++++ Utility/Inc/utility_tag.hpp | 12 +++++++ 4 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 Utility/Inc/utility_tag.hpp diff --git a/Peripherals/Inc/peripherals_utility.hpp b/Peripherals/Inc/peripherals_utility.hpp index 34b2691..0ab29af 100644 --- a/Peripherals/Inc/peripherals_utility.hpp +++ b/Peripherals/Inc/peripherals_utility.hpp @@ -15,10 +15,6 @@ namespace Peripherals { -#define SKULLC_CONCAT_IMPL(x, y) x##y -#define SKULLC_CONCAT(x, y) SKULLC_CONCAT_IMPL(x, y) -#define SKULLC_TAG struct SKULLC_CONCAT(SkullCTag_, __COUNTER__) - template constexpr const T& clamp(const T& v, const T& lo, const T& hi) { diff --git a/Tests/function.cpp b/Tests/function.cpp index a9dbe19..c7383fc 100644 --- a/Tests/function.cpp +++ b/Tests/function.cpp @@ -5,6 +5,7 @@ #include #include +#include TEST_CASE("Function calls function appropriately.", "[utility],[function]") { @@ -38,6 +39,26 @@ TEST_CASE("Function passes arguments appropriately.", "[utility],[function]") REQUIRE(bool_to_set == true); } +TEST_CASE("Function works with toStaticFunction.", "[utility],[function]") +{ + static int int_to_set = 0; + static bool bool_to_set = false; + + auto func_to_call = [](const int i, const bool b) { + int_to_set = i; + bool_to_set = b; + }; + + Utility::Function function(func_to_call); + using signature = void (*)(int, bool); + + signature func_pointer = function.toStaticFunction(); + func_pointer(10, true); + + REQUIRE(int_to_set == 10); + REQUIRE(bool_to_set == true); +} + TEST_CASE("FunctionOwned calls function appropriately.", "[utility],[function]") { struct S @@ -82,3 +103,29 @@ TEST_CASE("FunctionOwned passes arguments appropriately.", "[utility],[function] REQUIRE(subject.int_to_set == 10); REQUIRE(subject.bool_to_set == false); } + +TEST_CASE("FunctionOwned works with toStaticFunction.", "[utility],[function]") +{ + struct S + { + int int_to_set = 0; + bool bool_to_set = true; + + void toCall(const int i, const bool b) + { + int_to_set = i; + bool_to_set = b; + } + }; + + S subject; + + Utility::FunctionOwned function(subject, &S::toCall); + using signature = void (*)(int, bool); + + signature func_pointer = function.toStaticFunction(); + func_pointer(10, true); + + REQUIRE(subject.int_to_set == 10); + REQUIRE(subject.bool_to_set == true); +} diff --git a/Utility/Inc/utility_function.hpp b/Utility/Inc/utility_function.hpp index 4d9f200..e01078c 100644 --- a/Utility/Inc/utility_function.hpp +++ b/Utility/Inc/utility_function.hpp @@ -19,11 +19,19 @@ class IFunction { public: using result_type = R; + using static_signature = R (*)(Args...); virtual ~IFunction() {} virtual result_type operator()(Args... args) = 0; + + template + static_signature toStaticFunction() + { + static decltype(this) h = this; + return +[](Args... args) { (*h)(args...); }; + } }; template diff --git a/Utility/Inc/utility_tag.hpp b/Utility/Inc/utility_tag.hpp new file mode 100644 index 0000000..99eb900 --- /dev/null +++ b/Utility/Inc/utility_tag.hpp @@ -0,0 +1,12 @@ +// +// Created by erki on 26.06.22. +// + +#ifndef SKULLC_UTILITY_TAG_HPP_ +#define SKULLC_UTILITY_TAG_HPP_ + +#define SKULLC_CONCAT_IMPL(x, y) x##y +#define SKULLC_CONCAT(x, y) SKULLC_CONCAT_IMPL(x, y) +#define SKULLC_TAG struct SKULLC_CONCAT(SkullCTag_, __COUNTER__) + +#endif// SKULLC_UTILITY_TAG_HPP_