On Tue, Feb 1, 2022 at 8:05 AM Barry Revzin <barry.revzin@gmail.com> wrote:
I'm not an author of P1240, but...

On Tue, Feb 1, 2022 at 12:24 AM Matus Chochlik via SG7 <sg7@lists.isocpp.org> wrote:
ADL still works on std::meta::info, so is_named(^int) is valid by itself.
OK, good.
 

2) is it / will it be possible for the "filters" in members_of to be lambdas or other boolean-returning callables?

I think that's the point, yeah. As opposed to?
I see. I was confused by what is for example the `is_nonstatic_data_member`  `members_of(class_type, is_nonstatic_data_member)`. It might be useful to have an example with a lambda in the paper.

Another question, can I do unreflection in that lambda?
members_of(^foo, [](info mo) { return another_predicate([: transform(mo) :]); });
 

3) I have found that there are many use-cases (implementing RPC boilerplate, implementing SQL generator, implementing the factory pattern, and more) where there is a set of functions like foo, bar, baz that are calling each other, which operate on `reflections` (of base-level "things" that are not reified on the base level, like a constructor, a namespace, an expression) that are passed from outside to the algorithm, and
splicing is done in the innermost function.
pseudocode:

auto baz(metaobject auto mo) {
   return do_something([: mo :]);
}

auto bar(metaobject auto mo, auto arg1, auto arg2) {
   return baz(transform1(transform2(mo, arg2), arg1);
}

auto foo(metaobject auto mo, auto arg1, auto arg2. auto arg3) {
    return bar(transform3(mo, arg3));
}

cout << foo(^std, 1, '2', "3");

Is it correct that the only way to do this with meta info is to pass the metaobject in template arguments?

Can you provide a more real example?
Sure (RPC):
The place where the algo is implemented:
https://github.com/matus-chochlik/mirror/blob/32a0ee8247dce57f51b40e8cb9c5ebe1aa5d02f6/example/mirror/fake_rpc.cpp#L58
The place where the algo is called (note that a reflection of an expression is passed down, which cannot be done on the base-level):
https://github.com/matus-chochlik/mirror/blob/32a0ee8247dce57f51b40e8cb9c5ebe1aa5d02f6/example/mirror/fake_rpc.cpp#L128

Similar thing here:
implementation:
https://github.com/matus-chochlik/mirror/blob/32a0ee8247dce57f51b40e8cb9c5ebe1aa5d02f6/example/mirror/sql_query_generator.cpp#L35
invocation:
https://github.com/matus-chochlik/mirror/blob/32a0ee8247dce57f51b40e8cb9c5ebe1aa5d02f6/example/mirror/sql_query_generator.cpp#L70

In there a reflection of a constructor is passed around:
https://github.com/matus-chochlik/mirror/blob/develop/include/mirror/factory/builder.hpp

I've done this same thing with the lock3/meta implementation and it required some ugly workarounds in some places (I've presented it in SG7 some time ago).
 

template <std::meta::info mo> auto baz() {
    return do_something([: mo :]);
}
template <std::meta::info mo> auto bar(auto arg1, auto arg2) {
    return bar<transform1<transform2<mo>(arg2)>(arg1)>();
}
template <std::meta::info mo> auto foo(auto arg1, auto arg2, auto arg3) {
    return bar<transform3<mo>(arg3)>(arg1, arg2);
}

cout << baz<^std>(1, '2', "3")

I suppose the real question is: Does this work?

consteval auto f(std::meta::info type) {
    return sizeof([:type:]);
}

And the answer is no: in the paper, [: refl:] is only valid if refl is a constant expression. Which, until we get constexpr function parameters, means it must be passed as a template parameter.

So, what is the timeline on that?
Will such parameters be faster to compile than say using `wrapper<meta::info>` and if so can the same technique be used to improve compile-time performance of `__maybe_builtin_wrapper<meta::info>`?