From e5c5df5373ab4ad73e5415b63b0e5163c1bc23a7 Mon Sep 17 00:00:00 2001 From: Erki Date: Sat, 3 Jul 2021 12:09:25 +0300 Subject: [PATCH] Utility: add Function and FunctionOwned classes --- Tests/CMakeLists.txt | 2 +- Tests/function.cpp | 84 ++++++++++++++++++++++++++++++++ Utility/Inc/utility_function.hpp | 72 +++++++++++++++++++++++++++ 3 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 Tests/function.cpp create mode 100644 Utility/Inc/utility_function.hpp diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index a654247..cdb718a 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -18,7 +18,7 @@ add_executable(tests rand.cpp fixedpoint.cpp pixelbuffer.cpp - pixelbuffer_effects.cpp) + pixelbuffer_effects.cpp function.cpp) target_link_libraries(tests PUBLIC diff --git a/Tests/function.cpp b/Tests/function.cpp new file mode 100644 index 0000000..a9dbe19 --- /dev/null +++ b/Tests/function.cpp @@ -0,0 +1,84 @@ +// +// Created by erki on 03.07.21. +// + +#include + +#include + +TEST_CASE("Function calls function appropriately.", "[utility],[function]") +{ + static bool func_called = false; + + auto func_to_call = []() { + func_called = true; + }; + + Utility::Function function(func_to_call); + function(); + + REQUIRE(func_called == true); +} + +TEST_CASE("Function passes arguments appropriately.", "[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); + + function(10, true); + + REQUIRE(int_to_set == 10); + REQUIRE(bool_to_set == true); +} + +TEST_CASE("FunctionOwned calls function appropriately.", "[utility],[function]") +{ + struct S + { + bool to_set = false; + + void toCall() + { + to_set = true; + } + }; + + S subject; + + Utility::FunctionOwned function(subject, &S::toCall); + + function(); + + REQUIRE(subject.to_set == true); +} + +TEST_CASE("FunctionOwned passes arguments appropriately.", "[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); + + function(10, false); + + REQUIRE(subject.int_to_set == 10); + REQUIRE(subject.bool_to_set == false); +} diff --git a/Utility/Inc/utility_function.hpp b/Utility/Inc/utility_function.hpp new file mode 100644 index 0000000..2ea32c8 --- /dev/null +++ b/Utility/Inc/utility_function.hpp @@ -0,0 +1,72 @@ +/* + * utility_function.hpp + * + * Created on: Jun 20, 2021 + * Author: erki + */ + +#ifndef SKULLC_UTILITY_FUNCTION_HPP_ +#define SKULLC_UTILITY_FUNCTION_HPP_ + +namespace Utility +{ + +template +class Function; + +template +class Function +{ +public: + using result_type = R; + + using signature = R (*)(Args...); + + Function() = delete; + explicit Function(signature callable) + : callable_(callable) + { + assert(callable_); + } + + result_type operator()(Args&&... args) + { + return (*callable_)(std::forward(args)...); + } + +private: + signature callable_ = nullptr; +}; + +template +class FunctionOwned; + +template +class FunctionOwned +{ +public: + using source = H; + using result_type = R; + + using signature = R (source::*)(Args...); + + FunctionOwned() = delete; + explicit FunctionOwned(source& src, signature callable) + : src_(&src), callable_(callable) + { + assert(callable_); + } + + result_type operator()(Args&&... args) + { + return (src_->*callable_)(std::forward(args)...); + } + +private: + source* src_ = nullptr; + signature callable_ = nullptr; +}; + +}// namespace Utility + +#endif /* SKULLC_UTILITY_FUNCTION_HPP_ */