D compile-time function type extraction - function

D2.056
Function is a struct holding the name and the type of the function (Name and Type respectively). Binds iterates over a list of Function structs and returns a mixin string. This mixin defines for each function a new name with a '2' appended.
void f() { writeln("f"); }
void g() { writeln("g"); }
struct Function(string name, Prototype)
{
const string Name = name;
mixin("alias Prototype Type;");
}
string Binds(Functions...)()
{
string r;
foreach (F; Functions)
{
// error:
r ~= to!string(typeid(F.Type)) ~ " " ~ F.Name ~ "2 = &" ~ F.Name ~ ";";
}
return r;
}
int main()
{
mixin (Binds!(
Function!("f", void function()),
Function!("g", void function())
));
f();
//f2();
return 0;
}
When compiling, the to!string(typeid(F.Type)) gives an error:
Error: Cannot interpret & D13TypeInfo_PFZv6__initZ at compile time
called from here: to(& D13TypeInfo_PFZv6__initZ)
called from here: Binds()
Firstly, I don't see why an explicit conversion to string is required (isn't typeid already a string, if not, whats the difference between typeid and typeof?).
Secondly, I can't figure out how to get the explicit function type written out so that it can be executed in main. I can't use F.Type since it is local to the foreach.

You've got a couple problems here, but the main one is that typeid returns an object of type TypeInfo (typeid expression). Fortunately, you can just use F.Type.stringof. Also note that you don't need the mixin to alias Prototype as Type:
void f() { writeln("f"); }
void g() { writeln("g"); }
struct Function(string name, Prototype)
{
const string Name = name;
alias Prototype Type;
}
string Binds(Functions...)()
{
string r;
foreach (F; Functions)
{
// error:
r ~= F.Type.stringof ~ " " ~ F.Name ~ "2 = &" ~ F.Name ~ ";";
}
return r;
}
import std.stdio,
std.conv;
int main()
{
mixin (Binds!(
Function!("f", void function()),
Function!("g", void function())
));
f();
f2();
return 0;
}
Running this prints:
f
f
which I believe is what you're looking for.

Related

AST MATCHER:How to match un init double param in constructor

I 'm having a question to match uninit double field in constructor.
Given the code below
class un_init_double {
public:
un_init_double() {
init_param_ = 0;
}
bool compare(un_init_double& other) {
if (other.un_init_param_ == un_init_param_) {
return true;
}
return false;
}
private:
double un_init_param_;
double init_param_;
};
I want to match the un_init_param_ field, which didn't call binary operator = in constructor. But I don't find the method to do that.
I type below command in clang-query
clang-query> match cxxRecordDecl(
has(fieldDecl(hasType(asString("double"))).bind("double_field")), has(cxxConstructorDecl(hasDescendant(binaryOperator(hasEitherOperand(memberExpr()))))))
But how to specify memberExpr is related with prew part fieldDecl? In another word, how to specify the connection of fieldDecl and the memberExpr?
I find a method to match init_param_, but how to find no match field?
clang-query> match cxxRecordDecl(has(cxxConstructorDecl(hasDescendant(binaryOperator(hasEitherOperand(memberExpr(hasDeclaration(fieldDecl(hasType(asString("double"))))).bind("member")))))))
Match #1:
~/code_test/ast_matcher/test.cc:9:7: note: "member" binds here
init_param_ = 0;
^~~~~~~~~~~
~/code_test/ast_matcher/test.cc:6:1: note: "root" binds here
class un_init_double {
^~~~~~~~~~~~~~~~~~~~~~
1 match.
clang-query>
When debuging, I write a complicated method to perform this check:
// match record
cxxRecordDecl(
has(
// constuctor has init double fieldDecl with binaryoperator = , bind to init_double_field
cxxConstructorDecl(
hasDescendant(
binaryOperator(
hasOperatorName("="),
hasEitherOperand(memberExpr(hasDeclaration(fieldDecl(hasType(asString("double"))).bind("init_double_field"))))
)
)
)
),
has(
// match double field which didn't call binaryoperator = in constructor
fieldDecl(hasType(asString("double")), unless(equalsBoundNode("init_double_field"))).bind("un_init_double_field")
)
)
It seems to work, but if I add a sentence: "un_init_param_ = 1;" in the constructor, it still takes un_init_param_ as uninit_field. Find that it's caused by ast matcher will only match the first one rather than match all. So I modify matcher to:
cxxRecordDecl(
has(
cxxConstructorDecl(
forEachDescendant(
binaryOperator(
hasOperatorName("="),
hasEitherOperand(memberExpr(hasDeclaration(fieldDecl(hasType(asString("double"))).bind("init_double_field"))))
)
)
)
),
has(
fieldDecl(hasType(asString("double")), unless(equalsBoundNode("init_double_field"))).bind("un_init_double_field")
)
)
I modify original test.cpp to:
int f(int x) {
int result = (x / 42);
return result;
}
class un_init_double {
public:
un_init_double() {
init_param_0_ = 0;
init_param_1_ = 0;
}
bool compare(un_init_double& other) {
if (other.un_init_param_ == un_init_param_) {
return true;
}
return false;
}
private:
double un_init_param_;
double init_param_0_;
double init_param_1_;
};
New ast matcher can match it as follows:
Match #1:
/home/qcraft/code_test/ast_dump/test.cpp:20:5: note: "init_double_field" binds here
double init_param_0_;
^~~~~~~~~~~~~~~~~~~~
/home/qcraft/code_test/ast_dump/test.cpp:6:1: note: "root" binds here
class un_init_double {
^~~~~~~~~~~~~~~~~~~~~~
/home/qcraft/code_test/ast_dump/test.cpp:19:5: note: "un_init_double_field" binds here
double un_init_param_;
^~~~~~~~~~~~~~~~~~~~~
Match #2:
/home/qcraft/code_test/ast_dump/test.cpp:21:5: note: "init_double_field" binds here
double init_param_1_;
^~~~~~~~~~~~~~~~~~~~
/home/qcraft/code_test/ast_dump/test.cpp:6:1: note: "root" binds here
class un_init_double {
^~~~~~~~~~~~~~~~~~~~~~
/home/qcraft/code_test/ast_dump/test.cpp:19:5: note: "un_init_double_field" binds here
double un_init_param_;
^~~~~~~~~~~~~~~~~~~~~
2 matches.
clang-query>

Parameters KFunction in Kotlin

I have a class that has the type parameter KFunction<*>
(It is understood that I will indicate the type of function that I want to work with in the future)
I want a class method to take the same parameters that KFunction has and call subscribers with those arguments. However, I don't know how to get the type of the function parameters. There are delegates in C #. How to do something like this in Kotlin?
My class:
class Event<Function: KFunction<*>> {
val subscribers = mutableListOf<Function>()
operator fun plus(increment: Function) {
subscribers.add(increment)
}
// i want arguments as KFunction
operator fun invoke(args: ???) {
subscribers.forEach { it(args) }
}
}
fun c(i: Int) {
println("result of function c: $i")
}
fun main() {
val event = Event<KFunction1<Int, Unit>>()
event + ::c
event(100) // passing arguments Int from KFunction1<Int, Unit>
}
Is there a way to implement my idea exactly like this?
So, it's implied that type, passed as a Function : KFunction<*> type parameter (KFunction1<Int, Unit> in this case) will have its own type parameters (Int and Unit in this case), and you want to declare args parameter as an uncertain amount of parameters with these exact types (excluding the last one, which represents type of function call result)?
I believe it's impossible.
The best you can do is to declare args as vararg with Any? type:
operator fun invoke(vararg args: Any?) = subscribers.forEach { it.call(*args) }
It seems that the only normal solution to problem is to accept only 1 abstract type of parameters.
class Event<ArgsT> {
private val subscribers = mutableListOf<(ArgsT) -> Any>()
operator fun plusAssign(increment: (ArgsT) -> Any) {
subscribers.add(increment)
}
operator fun invoke(params: ArgsT) {
subscribers.forEach { it(params) }
}
}
fun c(i: Int, b: Int) {
println(i + b)
}
data class Data(val i: Int, val b: Int)
fun main() {
val event = Event<Data>()
event += { (i, b) -> c(i, b) } // pass arguments using a lambda
event(Data(2, 5))
}

How to get thrust::pair first and second use javacpp

From https://github.com/bytedeco/javacpp/wiki/Interface-Thrust-and-CUDA, I write thrust java code. Struct field is public by default, but I use first() method to get the first field value of thrust::pair, error happen.
error: expression preceding parentheses of apparent call must have (pointer-to-) function type
error: macro "offsetof" passed 3 arguments, but takes just 2
{ sizeof(thrust::pair), offsetof(thrust::pair, first) },
So how to get thrust::pair first and second value ?
#Platform(include="<thrust/pair.h>")
#Namespace("thrust")
public class Thrust {
static { Loader.load(); }
#Name("pair<int, double>")
public static class Pair extends Pointer {
static { Loader.load(); }
public Pair(IntPointer key, DoublePointer value){
allocate(key, value);
}
private native void allocate(#ByRef IntPointer k, #ByRef DoublePointer v);
// will happen error: expression preceding parentheses of apparent call must have (pointer-to-) function type
public native IntPointer first();
// will happen error: macro "offsetof" passed 3 arguments, but takes just 2
{ sizeof(thrust::pair<int, double>), offsetof(thrust::pair<int, double>, first) },
public native Pair first(IntPointer p);
}
public static void main(String[] args) {
IntPointer i = new IntPointer(1);
i.put(10);
DoublePointer d = new DoublePointer(1);
d.put(10.0);
Pair p = new Pair(i, d);
System.out.println(p.first());
}
}

How to initialize c++/cx class with aggregate initialization?

I have this ref class:
namespace N
{
public ref class S sealed
{
public:
property Platform::String^ x;
};
}
How do I initialize it in place with the aggregate initializer?
I have tried:
N::S s1 = { %Platform::String(L"text") };
but the compiler says
error C2440: 'initializing': cannot convert from 'initializer list' to
'N::S'
Also:
N::S s1 { %Platform::String(L"text") };
and the error is:
error C2664: 'N::S::S(const N::S %)': cannot convert argument 1 from
'Platform::String ^' to 'const N::S %'
This works greatly with the standard c++ like this:
struct T
{
wstring x;
};
T x { L"test" };
I do not want to use a constructor here.
I assume you mean you don't want a public constructor on the projected WinRT type -- no problem, you can use the internal keyword to mean "public inside C++ but not exposed through interop". That means you can even use native C++ types for your parameters if you like:
namespace Testing
{
public ref class MyTest sealed
{
public:
property String^ Foo {
String^ get() { return m_foo; }
void set(String^ value) { m_foo = value; }
}
internal:
// Would not compile if it was public, since wchar_t* isn't valid
MyTest(const wchar_t* value) { m_foo = ref new String(value); }
private:
String^ m_foo;
};
}
MainPage::MainPage()
{
// Projected type does NOT have this constructor
Testing::MyTest t{ L"Hello" };
OutputDebugString(t.Foo->Data());
t.Foo = "\nChanged";
OutputDebugString(t.Foo->Data());
}
Also you don't need to have the private variable to hold the string -- you could just use the auto-property as in your original code -- but I prefer to be explicit. It also means that if you needed to access the string a lot from within your C++ code you could provide an internal accessor function and not have to go through a vtable call to get at it.

Is there a way to convert a function variable to a string in D?

Is there any way, given a function variable, to get the name of the function as a string? For example, if I have:
void function(int) func;
Is there some function x() such that I could get:
x(func) == "func";
? I feel like this would be possible using mixins, but I'm confused as to how to implement this.
func.stringof
is what you need.
You could also make a template:
template Name(alias Func) { enum Name = Func.stringof; }
void func() { }
pragma(msg, Name!(func)); //prints func()
Simplest solution that comes to my mind:
You can have its name stored in a string, and mixin'ed where necessary, something like:
string func_name = "func";
...
int param = 294;
mixin(func_name ~ "(" ~ to!string(param) ~ ")");