Skip to content

Instantly share code, notes, and snippets.

@ajx42
Created July 25, 2022 08:10
Show Gist options
  • Save ajx42/4dd25e66bc739c12dd40a8f9c378aa49 to your computer and use it in GitHub Desktop.
Save ajx42/4dd25e66bc739c12dd40a8f9c378aa49 to your computer and use it in GitHub Desktop.
Functional Decorators (C++)
#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