Last active
January 24, 2021 15:08
-
-
Save plasma-effect/9903100b9bdf609eb6200b9307515543 to your computer and use it in GitHub Desktop.
PythonのデコレーターをC++で再現しようと思ったらよくわからないバケモンが完成した
This file contains hidden or 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
// copyright (c) 2021 M.K (a.k.a plasma-effect) | |
// Distributed under the Boost Software License, Version 1.0. | |
// (See http://www.boost.org/LICENSE_1_0.txt) | |
#pragma once | |
#include <utility> | |
#include <tuple> | |
namespace cpp_decorator | |
{ | |
namespace detail | |
{ | |
template<class FuncData, class Base, class IndexSequence, class Tuple>struct decorator; | |
template<class Return, class... FuncArgs, class Base, std::size_t... Is, class Tuple> | |
struct decorator<Return(FuncArgs...), Base, std::index_sequence<Is...>, Tuple> | |
{ | |
Base base; | |
Tuple args; | |
template<class Func>constexpr auto operator<<=(Func func)const | |
{ | |
return [base=base, args=args, func=func](FuncArgs... fargs)->Return | |
{ | |
return base(func, std::get<Is>(args)...)(fargs...); | |
}; | |
} | |
}; | |
template<class FuncData, class Base>struct decorator_t; | |
template<class Return, class... FuncArgs, class Base> | |
struct decorator_t<Return(FuncArgs...), Base> | |
{ | |
Base base; | |
template<class... Args>constexpr auto operator()(Args... args)const | |
{ | |
auto t = std::make_tuple(args...); | |
return decorator<Return(FuncArgs...), Base, std::make_index_sequence<sizeof...(Args)>, decltype(t)>{base, t}; | |
} | |
}; | |
template<class FuncData>struct decorator_t2; | |
template<class Return, class... FuncArgs> | |
struct decorator_t2<Return(FuncArgs...)> | |
{ | |
template<class Base>constexpr auto operator()(Base base)const | |
{ | |
return decorator_t<Return(FuncArgs...), Base>{base}; | |
} | |
}; | |
} | |
template<class FuncData>constexpr detail::decorator_t2<FuncData> decorator; | |
} |
This file contains hidden or 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 "decorator.hpp" | |
#include <functional> | |
#include <iostream> | |
using namespace cpp_decorator; | |
auto add_i(std::function<int(int)> func, int v) | |
{ | |
return [=](int u) | |
{ | |
return func(u) + v; | |
}; | |
} | |
auto mul_i(std::function<int(int)> func, int v) | |
{ | |
return [=](int u) | |
{ | |
return func(u) * v; | |
}; | |
} | |
constexpr auto add = decorator<int(int)>(add_i); | |
constexpr auto mul = decorator<int(int)>(mul_i); | |
auto func = mul(2) <<= add(1) <<= [&](int v) | |
{ | |
return 2 * v; | |
}; | |
int main() | |
{ | |
std::cout << func(5) << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment