Created
July 25, 2022 08:10
-
-
Save ajx42/4dd25e66bc739c12dd40a8f9c378aa49 to your computer and use it in GitHub Desktop.
Functional Decorators (C++)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <sstream> | |
#include <string> | |
#include <functional> | |
struct Logger | |
{ | |
Logger( const std::function<void(void)>& func, std::string name ) | |
: func { func }, name { name } {} | |
void operator()() | |
{ | |
std::cout << "Entering Function " << name << std::endl; | |
func(); | |
std::cout << "Exiting " << name << std::endl; | |
} | |
private: | |
std::function<void(void)> func; | |
std::string name; | |
}; | |
template <typename Func> | |
struct GenericLogger | |
{ | |
GenericLogger( const Func& func, std::string name ) | |
: func { func }, name { name } {} | |
void operator()() | |
{ | |
std::cout << "Entering via GenericLogger Function " << name << std::endl; | |
func(); | |
std::cout << "Exiting " << name << std::endl; | |
} | |
private: | |
Func func; | |
std::string name; | |
}; | |
template <typename> struct FunctionalLogger; | |
template <typename R, typename ...Args> | |
struct FunctionalLogger<R(Args...)> | |
{ | |
FunctionalLogger( const std::function<R(Args...)>& func, std::string name ) | |
: func { func }, name { name } {} | |
R operator()( Args ...args ) | |
{ | |
std::cout << "Entering via FunctionalLogger Function " << name << std::endl; | |
auto result = func( std::forward<Args>(args)... ); | |
std::cout << "Exiting " << name << std::endl; | |
return result; | |
} | |
private: | |
std::function<R(Args...)> func; | |
std::string name; | |
}; | |
template <typename R, typename ...Args> | |
FunctionalLogger<R(Args...)> makeFuncLogger( | |
R (*func)( Args... ), std::string name ) | |
{ | |
return FunctionalLogger<R(Args...)>( | |
std::function<R(Args...)>( func ), name | |
); | |
} | |
int add2Numbers( int x, int y ) | |
{ | |
std::cout << "x=" << x << " y=" << y << std::endl; | |
return x + y; | |
} | |
int main() | |
{ | |
auto loggedHello = GenericLogger( | |
[](){ std::cout << "Hello World" << std::endl; }, | |
"SayHello()" | |
); | |
loggedHello(); | |
auto withReturnDouble = FunctionalLogger<int(int)>( | |
[]( int x ) -> int { std::cout << "x=" << x << std::endl; return x*2; }, | |
"double()" | |
); | |
std::cout << withReturnDouble(4) << std::endl; | |
auto funcLogger = makeFuncLogger( add2Numbers, "add2Numbers()"); | |
std::cout << funcLogger(5, 10) << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment