On Jun 10, 2021, at 11:41 AM, Dvir Yitzchaki via SG7 <sg7@lists.isocpp.org> wrote:Hi.
I’ve been playing around implementing a feature similar to python decorators using the reflection implementation in https://github.com/lock3/meta, based on the [P1240](https://wg21.link/P1240] syntax.
Currently I’ve managed to compile the following code on my branch:#include <experimental/compiler> #include <experimental/meta> #include <iostream> #include <utility> #define FWD(x) std::forward<decltype(x)>(x) namespace meta = std::experimental::meta; using string_type = const char*; constexpr bool string_eq(string_type s1, string_type s2) { while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; } return *s1 == *s2; } consteval void decorate(meta::info source) { for (auto mem : meta::members_of(source)) { if (meta::has_attribute(mem, "decorator")) { if (not meta::is_function(mem)) { meta::compiler.error("can only decorate functions"); } for (const auto attribute : meta::attributes_of(mem)) { if (string_eq(meta::name_of(attribute), "decorator")) { for (const auto decorator : meta::attribute_arguments_of(attribute)) { ->fragment struct { template <typename... Args> static auto unqualid(% {mem})(Args&&... args) { return idexpr(% {decorator})(idexpr(% {mem}))(FWD(args)...); } }; } meta::set_new_name(mem, __concatenate("orig_", meta::name_of(mem))); ->mem; } } } } } template <typename F> auto logger(F&& f) { return [f]<typename... Args>(Args && ... args) { std::cout << "calling " << meta::name_of(reflexpr(f)); std::cout << "("; (void)(std::cout << ... << args); std::cout << ")\n"; return f(FWD(args)...); }; } struct(decorate) Foo{ [[decorator(logger)]] static void fn(int){} }; int main() { meta::compiler.print(reflexpr(Foo)); Foo::fn(42); }with this output (from a local compiler explorer I run)
ASM generation compiler returned: 0 struct Foo { template <typename ...Args> static auto fn(Args &&...args) { return logger(fn)(std::forward<decltype(args)>(args)...); } static void orig_fn(int) { } }; Execution build compiler returned: 0 Program returned: 0 calling f(42)For this to work I had to tell clang not to remove unknown attributes as well as add some attribute reflection functions to meta.
Do you think this is a valuable usage?
Do you think attribute reflection functions should be added to the standard meta library?
--Best regards,
Dvir
SG7 mailing list
SG7@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/sg7