Re: How to do reflection on alias symbols

2023-11-17 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, November 17, 2023 2:11:30 AM MST Arafel via Digitalmars-d-learn 
wrote:
> I mean, in order to know if something is an `enum`, I need to do:
>
> ```d
> enum isEnum(alias a) = is(typeof(a)) && !is(typeof());
> ```
>
> which feels like the wrong approach, and too much error-prone. I also
> fear I'm forgetting to consider some corner case.
>
> There is `is(E == enum)`, but it only works on types, and fails for
> anonymous enums, because `typeof` returns the base type.

Well, anonymous enums are what are called manifest constants, so they
literally aren't enums as far as their type goes, and the type system does
not consider them to be enums. They're just a way to declare constants
(they're essentialy the D equivalent of using #define for constants in
C/C++). Arguably, they should use a keyword other than enum (and that's been
debated in the past), but it's unlikely to change at this point.

So, if we were to add something to std.traits for them, it would probably be
something more like isManifestConstant than isEnum. In spite of the keyword
being used, they really aren't intended to be considered enums.

- Jonathan M Davis





Re: How to do reflection on alias symbols

2023-11-17 Thread Arafel via Digitalmars-d-learn

On 17/11/23 2:48, Jonathan M Davis wrote:

On Thursday, November 16, 2023 6:04:43 PM MST Jonathan M Davis via
Digitalmars-d-learn wrote:

Actually, it looks like there's already an old bug report on the issue:

https://issues.dlang.org/show_bug.cgi?id=12363

So, it has been reported, but it looks it's one of those that's gone under
the radar.

- Jonathan M Davis



Thanks for finding it!

I think that in general D could do with a more systematic approach to 
reflection. For me, it's one of its greatest features, and it's a bit of 
a pity that it needs to be done in such an ad-hoc manner with all kind 
of corner cases.


I mean, in order to know if something is an `enum`, I need to do:

```d
enum isEnum(alias a) = is(typeof(a)) && !is(typeof());
```

which feels like the wrong approach, and too much error-prone. I also 
fear I'm forgetting to consider some corner case.


There is `is(E == enum)`, but it only works on types, and fails for 
anonymous enums, because `typeof` returns the base type.


I know that `std.traits` was precisely supposed to hide these dirty 
details, but as of now it also seems to be missing this kind of 
systematic approach: I'd like things like `isEnum!symbol`, and also 
`isAlias!symbol`, etc.


But I think I digress a bit too much, this would be a topic rather for 
the general forum.


Thanks again for your help!


Re: How to do reflection on alias symbols

2023-11-16 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, November 16, 2023 6:04:43 PM MST Jonathan M Davis via 
Digitalmars-d-learn wrote:
> I would suggest that you open up a bug report for it -
> https://issues.dlang.org - and certainly, there's a good argument that what
> you're seeing here is a bug. I fully expect that what you're trying do just
> wasn't properly considered previously and thus was not dealt with properly
> when the other bugs for visibility attributes on aliases were fixed however
> many years ago that was now. I very much doubt that what you're seeing is
> the intended behavior - or at least I fully expect that if Walter or one of
> the other compiler devs sees the issue, they will agree that what you're
> trying to do should work.

Actually, it looks like there's already an old bug report on the issue:

https://issues.dlang.org/show_bug.cgi?id=12363

So, it has been reported, but it looks it's one of those that's gone under
the radar.

- Jonathan M Davis





Re: How to do reflection on alias symbols

2023-11-16 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, November 16, 2023 3:03:25 AM MST Arafel via Digitalmars-d-learn 
wrote:
> Hi all,
>
> Please consider the following currently non-working code:
>
> ```d
> struct bar {
>  public alias pubInt = int;
>  private alias privInt = int;
> }
>
> static foreach(member ; __traits(allMembers, bar)) {
>  // Error: argument `int` has no visibility
>  pragma(msg, __traits(getVisibility, __traits(getMember, bar, member)));
> }
> ```
>
> Is there any way to get the visibility, or more generically to reflect
> on an alias member as itself and not as the symbol pointed to without
> resorting to nasty __trait(compiles,...) tricks that fail more often
> than not?

Someone may be able to give you some advice on how to better deal with this
problem, but in general, aliases don't really exist as far as the compiler
is concerned. They get translated to the original type and handled that way
rather than treated as a separate type that translates to another type. They
exist enough that you can do stuff like give them different visibility
attributes for the original symbol, but that pretty much just affects
whether you can use the alias, and then it gets replaced with the real thing
immediately. As it is, IIRC, it was previously the case that there were bugs
where visibility attributes did not affect aliases properly, so it's not at
all surprising if there isn't a good way to access the visibility attribute
of the alias itself.

I would suggest that you open up a bug report for it -
https://issues.dlang.org - and certainly, there's a good argument that what
you're seeing here is a bug. I fully expect that what you're trying do just
wasn't properly considered previously and thus was not dealt with properly
when the other bugs for visibility attributes on aliases were fixed however
many years ago that was now. I very much doubt that what you're seeing is
the intended behavior - or at least I fully expect that if Walter or one of
the other compiler devs sees the issue, they will agree that what you're
trying to do should work.

- Jonathan M Davis





How to do reflection on alias symbols

2023-11-16 Thread Arafel via Digitalmars-d-learn

Hi all,

Please consider the following currently non-working code:

```d
struct bar {
public alias pubInt = int;
private alias privInt = int;
}

static foreach(member ; __traits(allMembers, bar)) {
// Error: argument `int` has no visibility
pragma(msg, __traits(getVisibility, __traits(getMember, bar, member)));
}
```

Is there any way to get the visibility, or more generically to reflect 
on an alias member as itself and not as the symbol pointed to without 
resorting to nasty __trait(compiles,...) tricks that fail more often 
than not?


Re: Reflection on the book D web development.

2020-11-28 Thread Alaindevos via Digitalmars-d-learn

& Golang has Martini which is quite easy to use,
https://www.youtube.com/watch?v=tUFzdUIjVRg


Re: Reflection on the book D web development.

2020-11-25 Thread bachmeier via Digitalmars-d-learn

On Wednesday, 25 November 2020 at 17:26:44 UTC, Alaindevos wrote:

hunt-http has no documentation and does not looks usable to me.
What looks usable is kemal & the crystal language,
https://kemalcr.com/guide/


Looks like Sinatra. That makes sense given the relationship of 
Crystal to Ruby. Many languages have a Sinatra-inspired 
framework, but to my knowledge not D. I think Adam Ruppe's 
libraries are closer to that approach.


Re: Reflection on the book D web development.

2020-11-25 Thread Alaindevos via Digitalmars-d-learn

hunt-http has no documentation and does not looks usable to me.
What looks usable is kemal & the crystal language,
https://kemalcr.com/guide/


Re: Reflection on the book D web development.

2020-11-23 Thread bachmeier via Digitalmars-d-learn

On Saturday, 21 November 2020 at 16:18:39 UTC, Alaindevos wrote:
It's not my related to a lack of knowledge of the d-language 
but the complexity of the vibe.d framework itself.

What I understand are :
1: jade/diet .dt templates, inheritance,includes,markdown.
2: A simple form with POST method.
Then it stops.
What I find too complex:
- Sessions, session data , session variables
- Handler functions and delegates, compile-time reflection, 
prefixes, annotation.

- Authentication
- Validating user input
This can be improved by improving documentation in very small 
steps.


As comparison here a tutorial of ruby-flask which uses only 
small steps so everything can easily and completely be 
understood.

Something like that for vibe.d would be very interesting.
https://www.youtube.com/watch?v=3mwFC4SHY-Y


May or may not be related, but I eventually gave up on that book 
myself. It felt as if it were written for experienced web 
developers wanting to use D for things they were doing in other 
languages. It's been a long time now, though, so I don't recall 
anything specific.


Re: Reflection on the book D web development.

2020-11-21 Thread Alaindevos via Digitalmars-d-learn
It's not my related to a lack of knowledge of the d-language but 
the complexity of the vibe.d framework itself.

What I understand are :
1: jade/diet .dt templates, inheritance,includes,markdown.
2: A simple form with POST method.
Then it stops.
What I find too complex:
- Sessions, session data , session variables
- Handler functions and delegates, compile-time reflection, 
prefixes, annotation.

- Authentication
- Validating user input
This can be improved by improving documentation in very small 
steps.


As comparison here a tutorial of ruby-flask which uses only small 
steps so everything can easily and completely be understood.

Something like that for vibe.d would be very interesting.
https://www.youtube.com/watch?v=3mwFC4SHY-Y


Re: Reflection on the book D web development.

2020-11-21 Thread aberba via Digitalmars-d-learn

On Friday, 20 November 2020 at 19:12:38 UTC, Alaindevos wrote:

I bought the book "D Web Development".
I understand only 20% of the book,the other 80% is way above my 
head.
Compare, I own a book on flask development, and I understand 
100% of it.
Which means I can use dlang for anything except QT and serious 
web development ...


How would you like this to be improved? I'm personally interested 
in making vibe.d more accessible.





Re: Reflection on the book D web development.

2020-11-20 Thread CraigDillabaugh via Digitalmars-d-learn

On Friday, 20 November 2020 at 19:12:38 UTC, Alaindevos wrote:

I bought the book "D Web Development".
I understand only 20% of the book,the other 80% is way above my 
head.
Compare, I own a book on flask development, and I understand 
100% of it.
Which means I can use dlang for anything except QT and serious 
web development ...


Could you explain some of the things that you found particularly 
challenging about the book?   What level of D proficiency did you 
have before you started with the book?


Reflection on the book D web development.

2020-11-20 Thread Alaindevos via Digitalmars-d-learn

I bought the book "D Web Development".
I understand only 20% of the book,the other 80% is way above my 
head.
Compare, I own a book on flask development, and I understand 100% 
of it.
Which means I can use dlang for anything except QT and serious 
web development ...


Re: Run-time reflection for class inheritance

2019-12-02 Thread Michael Green via Digitalmars-d-learn

On Sunday, 1 December 2019 at 14:42:46 UTC, Adam D. Ruppe wrote:

You can get the type at runtime by simply casting it...

if(auto c = cast(EventSocket) event) {
   // is an event socket
}


Thanks.

I guess you need to be careful about which order you do those 
tests so as not to cast to more general types before testing for 
specific ones.


I also came up with

```
if (typeid(event) == typeid(EventTimer)) {
// do something
}
```

The reason I was leaning toward the first one is that it could be 
put in a switch as it's just string compares.


I guess having it cast as part of the check is useful.


Re: Run-time reflection for class inheritance

2019-12-01 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 1 December 2019 at 12:26:03 UTC, Michael Green wrote:
I don't know if this would be a sensible approach to try and 
get at the actual class types for objects stored in some 
container at runtime?


You can get the type at runtime by simply casting it...

if(auto c = cast(EventSocket) event) {
   // is an event socket
}


and then you can actually use the c object too.

Or if you put the necessary functionality in the interface then 
you simply call the method - this is better object-oriented 
design as it reduces the necessary knowledge for the function to 
use the object.


Re: Run-time reflection for class inheritance

2019-12-01 Thread Michael Green via Digitalmars-d-learn

On Sunday, 1 December 2019 at 12:26:03 UTC, Michael Green wrote:

interface Event {



[note to self - shouldn't make last minute checks and reverse 
them by hand before posting]


That should of course read:


class Event {


Run-time reflection for class inheritance

2019-12-01 Thread Michael Green via Digitalmars-d-learn
I don't know if this would be a sensible approach to try and get 
at the actual class types for objects stored in some container at 
runtime?


I have noticed that this approach doesn't work if Event is an 
interface rather than a ancestor class.



```
import std.stdio;
import std.string;
import std.traits;
import std.conv;

interface Event {
void report() {
writeln("an event");
}
}

class EventTimer : Event {
override void report() {
writeln("timer event");
}
}

class EventSocket: Event {
override void report() {
writeln("socket event");
}
}

void main(string[] args) {

Event[] events;

foreach (arg; args[1..$]) {
// just something to pick actual type at runtime
if (to!int(arg) > 5) {
events ~= new EventTimer();
} else {
events ~= new EventSocket();
}
}

foreach (event; events) {

switch (event.classinfo.name) {
case fullyQualifiedName!EventTimer:
writeln("found timer event");
break;
case fullyQualifiedName!EventSocket:
writeln("found socket event");
break;
default:
throw new Exception("unknown event type");
break;
}

event.report();
}
}
```


Re: Blog Post #0039 - File Dialog V - Adding SaveAs and Titlebar Filename Reflection

2019-05-28 Thread Ron Tarrant via Digitalmars-d-learn
Hi WebFreak. I'm glad you're getting something out of it. I 
started this because it's the kind of thing I wished was out 
there. It's good to know I'm not the only one.


On Tuesday, 28 May 2019 at 12:58:12 UTC, WebFreak001 wrote:


Could you maybe add screenshots to each blog post?


I've had a ton (Well, four... Five? Six?) requests to do them and 
I have started down that road, but it's going to take a bit of 
time what with everything else I've got going on ATM.


They could be shown for example right at the top of each post 
and maybe a thumbnail in the post list and that way greatly 
simplify searching a tutorial of interest and also massively 
help with sharing links to your posts online where OpenGraph or 
Twitter images are embedded. (see https://gethead.info/ for 
good examples how to add these meta tags)


I'll see if I can sort this out.


Is the source code of your site available somewhere?


I'm not sure what you mean by this... the HTML? the Jekyll code? 
Or are you asking about the example files? Because the examples 
are all there with links in the blog posts, if that's what you're 
asking about.


But if you're asking about the HTML/Jekyll/whatever, I have to 
ask: why do you want access?


Also it would be nice if it supported HTTPS. (LetsEncrypt 
certificates are free and easy to setup for this)


Why would I need secure pages?



Re: Blog Post #0039 - File Dialog V - Adding SaveAs and Titlebar Filename Reflection

2019-05-28 Thread WebFreak001 via Digitalmars-d-learn

On Tuesday, 28 May 2019 at 09:47:23 UTC, Ron Tarrant wrote:

Good day to you all.

'Tis another Tuesday and time for a new blog post. This is a 
continuation of the series on Dialogs and further, a 
continuation of the mini-series-within-a-series on file 
Dialogs. The subject is in the title as is fitting for a blog 
post about putting things in the titlebar.


You can find it here: 
http://gtkdcoding.com/2019/05/28/0039-file-save-as-dialog.html


nice work! Such regular tutorials are always great for the 
community and just recently recommended it to someone asking for 
one.


Could you maybe add screenshots to each blog post? They could be 
shown for example right at the top of each post and maybe a 
thumbnail in the post list and that way greatly simplify 
searching a tutorial of interest and also massively help with 
sharing links to your posts online where OpenGraph or Twitter 
images are embedded. (see https://gethead.info/ for good examples 
how to add these meta tags)


Is the source code of your site available somewhere? Also it 
would be nice if it supported HTTPS. (LetsEncrypt certificates 
are free and easy to setup for this)


Blog Post #0039 - File Dialog V - Adding SaveAs and Titlebar Filename Reflection

2019-05-28 Thread Ron Tarrant via Digitalmars-d-learn

Good day to you all.

'Tis another Tuesday and time for a new blog post. This is a 
continuation of the series on Dialogs and further, a continuation 
of the mini-series-within-a-series on file Dialogs. The subject 
is in the title as is fitting for a blog post about putting 
things in the titlebar.


You can find it here: 
http://gtkdcoding.com/2019/05/28/0039-file-save-as-dialog.html




Re: Derived classes? Reflection

2019-03-29 Thread Alex via Digitalmars-d-learn

On Saturday, 13 April 2013 at 17:50:00 UTC, Tofu Ninja wrote:

On Saturday, 13 April 2013 at 17:45:12 UTC, Tofu Ninja wrote:

Maybe this is helpfully:
http://forum.dlang.org/thread/scgjnudclnwlbdqqd...@forum.dlang.org


Oddly enough, I found that at about the same time you posted 
it.


Sadly this does not provide a compile time solution, only 
runtime.


I wonder if one could use this to first spawn a process at 
compile type and then spit out the information and then process 
that info at compile time(say from a text file).


Re: Converting member variables to strings with using reflection from base class

2017-12-22 Thread Mengu via Digitalmars-d-learn

On Friday, 22 December 2017 at 22:09:05 UTC, H. S. Teoh wrote:
On Fri, Dec 22, 2017 at 09:13:31PM +, kerdemdemir via 
Digitalmars-d-learn wrote:
I want to make a logging function for member variables by 
using reflection.

[...]

class B
{
void Log()
{
auto a = [__traits(derivedMembers, D)];
foreach(memberName; a) {
// Somehow write only member variables with their 
names

// Result should be : a = 4.0, b = 3.0


Try this:

import std.traits : FieldNameTuple;
foreach (memberName; FieldNameTuple!B) {
writefln("%s = %s", memberName, mixin("this." ~ memberName));
}


T


and then turn it into a LoggerMixin with a mixin template and 
re-use it any time you want.


import std.stdio : writeln, writefln;
import std.traits : FieldNameTuple;

mixin template LoggerMixin() {
  void Log() {
foreach (memberName; FieldNameTuple!(typeof(this))) {
  writefln("%s = %s", memberName, mixin("this." ~ 
memberName));

}

  }
}

struct S {
  int x;
  bool y;
  double z;

  mixin LoggerMixin;
}

void main() {

  S s1 = S(int.min, true, );
  S s2 = S(int.max, false, );
  s1.Log();
  s2.Log();
}



Re: Converting member variables to strings with using reflection from base class

2017-12-22 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Dec 22, 2017 at 09:13:31PM +, kerdemdemir via Digitalmars-d-learn 
wrote:
> I want to make a logging function for member variables by using reflection.
[...]
> class B
> {
> void Log()
> {
> auto a = [__traits(derivedMembers, D)];
> foreach(memberName; a) {
> // Somehow write only member variables with their names
> // Result should be : a = 4.0, b = 3.0

Try this:

import std.traits : FieldNameTuple;
foreach (memberName; FieldNameTuple!B) {
writefln("%s = %s", memberName, mixin("this." ~ memberName));
}


T

-- 
People walk. Computers run.


Converting member variables to strings with using reflection from base class

2017-12-22 Thread kerdemdemir via Digitalmars-d-learn
I want to make a logging function for member variables by using 
reflection.


import std.stdio;

class D : B
{
override void foo() {
a  = 4.0;
b  = 3.0;
}
double a;
double b;
}

class B
{
void Log()
{
auto a = [__traits(derivedMembers, D)];
foreach(memberName; a) {
// Somehow write only member variables with their 
names

// Result should be : a = 4.0, b = 3.0
}
}

void foo()
{
}
}

void main()
{
 auto b = new D;
 b.Log();
}

As I wrote in the comments I want to see member variable's name 
and its value.

What is the best way to achieve that?

Erdem


Re: learning reflection in D

2017-10-05 Thread drug via Digitalmars-d-learn

05.10.2017 18:04, Adam D. Ruppe пишет:

On Thursday, 5 October 2017 at 14:59:10 UTC, drug wrote:
1) why .stringof and typeid() is equal logically and different in 
fact? What is difference between them? Is it that stringof compile 
time and typeid runtime things? Anyway wouldn't it be better they will 
equal both logically and literally?


stringof is a static debugging aid, just a string that kinda represents 
it in code. It isn't guaranteed to match anything, but should be enough 
that when you eyeball it it points you in the right direction... you 
shouldn't rely on it to be anything specific. typeid, on the other hand, 
is a published, documented object with methods and defined comparisons. 
So that's one difference.


The other one is indeed compile time vs runtime: stringof is purely 
compile time, whereas typeid() returns a runtime object on a runtime 
object. To see the difference, try:


Object o = new MyClass();
typeid(o);


You'll see it is MyClass, but the static versions (stringof, typeof, 
etC) will all think of it as Object.



2) Where do these attributes come from? I mean `pure nothrow @nogc 
@safe` except `@property` that I set explicitly?


You didn't specify a return value for those functions, which meant the 
compiler inferred a bunch about it. It inferred the return value and 
those other attributes to fill in the gap.


If you gave an explicit return value `@property int` or `@property 
void`, then it wouldn't automatically fill stuff in anymore.

Thank you, Adam!


Re: learning reflection in D

2017-10-05 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 5 October 2017 at 14:59:10 UTC, drug wrote:
1) why .stringof and typeid() is equal logically and different 
in fact? What is difference between them? Is it that stringof 
compile time and typeid runtime things? Anyway wouldn't it be 
better they will equal both logically and literally?


stringof is a static debugging aid, just a string that kinda 
represents it in code. It isn't guaranteed to match anything, but 
should be enough that when you eyeball it it points you in the 
right direction... you shouldn't rely on it to be anything 
specific. typeid, on the other hand, is a published, documented 
object with methods and defined comparisons. So that's one 
difference.


The other one is indeed compile time vs runtime: stringof is 
purely compile time, whereas typeid() returns a runtime object on 
a runtime object. To see the difference, try:


Object o = new MyClass();
typeid(o);


You'll see it is MyClass, but the static versions (stringof, 
typeof, etC) will all think of it as Object.



2) Where do these attributes come from? I mean `pure nothrow 
@nogc @safe` except `@property` that I set explicitly?


You didn't specify a return value for those functions, which 
meant the compiler inferred a bunch about it. It inferred the 
return value and those other attributes to fill in the gap.


If you gave an explicit return value `@property int` or 
`@property void`, then it wouldn't automatically fill stuff in 
anymore.


learning reflection in D

2017-10-05 Thread drug via Digitalmars-d-learn

https://run.dlang.io/is/8LbmzG

1) why .stringof and typeid() is equal logically and different in fact? 
What is difference between them? Is it that stringof compile time and 
typeid runtime things? Anyway wouldn't it be better they will equal both 
logically and literally?
2) Where do these attributes come from? I mean `pure nothrow @nogc 
@safe` except `@property` that I set explicitly?


Re: Deduplicating template reflection code

2017-04-14 Thread Moritz Maxeiner via Digitalmars-d-learn

On Friday, 14 April 2017 at 17:57:49 UTC, Johannes Pfau wrote:

Am Fri, 14 Apr 2017 13:41:45 +
schrieb Moritz Maxeiner :


[...]


Great, thanks that's exactly the solution I wanted. Figuring 
this out by myself is a bit above my template skill level ;-)



-- Johannes



No problem, I often enough encounter instances of 
THE DAMNED COMPILER JUST NOT DOING WHAT I 
WANT being frustrated with templates myself. 
Usually looking at phobos code helps, though.


Re: Deduplicating template reflection code

2017-04-14 Thread Johannes Pfau via Digitalmars-d-learn
Am Fri, 14 Apr 2017 13:41:45 +
schrieb Moritz Maxeiner :

> On Friday, 14 April 2017 at 11:29:03 UTC, Johannes Pfau wrote:
> >
> > Is there some way to wrap the 'type selection'? In pseudo-code 
> > something like this:
> >
> > enum FilteredOverloads(API) = ...
> >
> > foreach(Overload, FilteredOverloads!API)
> > {
> > 
> > }  
> 
> Sure, but that's a bit more complex:
> 
> ---
> [...] // IgnoreUDA declaration
> [...] // isSpecialFunction declaration
> 
> ///
> template FilteredOverloads(API)
> {
>  import std.traits : hasUDA, isSomeFunction, 
> MemberFunctionsTuple;
>  import std.meta : staticMap;
>  import std.typetuple : TypeTuple;
> 
>  enum derivedMembers = __traits(derivedMembers, API);
> 
>  template MemberOverloads(string member)
>  {
>  static if (__traits(compiles, __traits(getMember, API, 
> member)))
>  {
>  static if (isSomeFunction!(__traits(getMember, API, 
> member))
> && !hasUDA!(__traits(getMember, API, 
> member), IgnoreUDA)
> && !isSpecialFunction!member) {
>  alias MemberOverloads = 
> MemberFunctionsTuple!(API, member);
>  } else {
>  alias MemberOverloads = TypeTuple!();
>  }
>  } else {
>  alias MemberOverloads = TypeTuple!();
>  }
>  }
> 
>  alias FilteredOverloads = staticMap!(MemberOverloads, 
> derivedMembers);
> }
> 
> //pragma(msg, FilteredOverloads!API);
> foreach(Overload; FilteredOverloads!API) {
>  // function dependent code here
> }
> ---
> 
> Nested templates and std.meta are your best friends if this is 
> the solution you prefer :)

Great, thanks that's exactly the solution I wanted. Figuring this out by
myself is a bit above my template skill level ;-)


-- Johannes



Re: Deduplicating template reflection code

2017-04-14 Thread Moritz Maxeiner via Digitalmars-d-learn

On Friday, 14 April 2017 at 11:29:03 UTC, Johannes Pfau wrote:


Is there some way to wrap the 'type selection'? In pseudo-code 
something like this:


enum FilteredOverloads(API) = ...

foreach(Overload, FilteredOverloads!API)
{

}


Sure, but that's a bit more complex:

---
[...] // IgnoreUDA declaration
[...] // isSpecialFunction declaration

///
template FilteredOverloads(API)
{
import std.traits : hasUDA, isSomeFunction, 
MemberFunctionsTuple;

import std.meta : staticMap;
import std.typetuple : TypeTuple;

enum derivedMembers = __traits(derivedMembers, API);

template MemberOverloads(string member)
{
static if (__traits(compiles, __traits(getMember, API, 
member)))

{
static if (isSomeFunction!(__traits(getMember, API, 
member))
   && !hasUDA!(__traits(getMember, API, 
member), IgnoreUDA)

   && !isSpecialFunction!member) {
alias MemberOverloads = 
MemberFunctionsTuple!(API, member);

} else {
alias MemberOverloads = TypeTuple!();
}
} else {
alias MemberOverloads = TypeTuple!();
}
}

alias FilteredOverloads = staticMap!(MemberOverloads, 
derivedMembers);

}

//pragma(msg, FilteredOverloads!API);
foreach(Overload; FilteredOverloads!API) {
// function dependent code here
}
---

Nested templates and std.meta are your best friends if this is 
the solution you prefer :)


Re: Deduplicating template reflection code

2017-04-14 Thread Johannes Pfau via Digitalmars-d-learn
Am Fri, 14 Apr 2017 08:55:48 +
schrieb Moritz Maxeiner :

> 
> mixin Foo!(API, (MethodType) {
> // function dependent code here
> });
> foo();
> ---
> 
> Option 2: Code generation using CTFE
> 
> ---
> string genFoo(alias API, string justDoIt)
> {
>  import std.array : appender;
>  auto code = appender!string;
>  code.put(`[...]1`);
>  code.put(`foreach (MethodType; overloads) {`);
>  code.put(justDoIt);
>  code put(`}`);
>  code.put(`[...]2`);
> }
> 
> mixin(genFoo!(API, q{
>  // function dependent code here
> })());
> ---
> 
> Personally, I'd consider the second approach to be idiomatic, but 
> YMMW.

I'd prefer the first approach, simply to avoid string mixins. I think
these can often get ugly ;-)

Is there some way to wrap the 'type selection'? In pseudo-code something
like this:

enum FilteredOverloads(API) = ...

foreach(Overload, FilteredOverloads!API)
{

}
-- Johannes



Re: Deduplicating template reflection code

2017-04-14 Thread Moritz Maxeiner via Digitalmars-d-learn

On Friday, 14 April 2017 at 08:24:00 UTC, Johannes Pfau wrote:

I've got this code duplicated in quite some functions:

-
[...]1

foreach (MethodType; overloads)
{
// function dependent code here
}
[...]2


What's the idiomatic way to refactor / reuse this code fragment?

-- Johannes


Your options are at least the following two (both untested, but 
should work):


Option 1: Template Mixins

---
mixin template Foo(alias API, Dg)
{
void foo()
{
   [...]1
 foreach (MethodType; overloads)
 {
Dg(MethodType);
 }
   [...]2
}
}

mixin Foo!(API, (MethodType) {
// function dependent code here
});
foo();
---

Option 2: Code generation using CTFE

---
string genFoo(alias API, string justDoIt)
{
import std.array : appender;
auto code = appender!string;
code.put(`[...]1`);
code.put(`foreach (MethodType; overloads) {`);
code.put(justDoIt);
code put(`}`);
code.put(`[...]2`);
}

mixin(genFoo!(API, q{
// function dependent code here
})());
---

Personally, I'd consider the second approach to be idiomatic, but 
YMMW.


Re: Deduplicating template reflection code

2017-04-14 Thread Stefan Koch via Digitalmars-d-learn

On Friday, 14 April 2017 at 08:24:00 UTC, Johannes Pfau wrote:

I've got this code duplicated in quite some functions:

-
foreach (member; __traits(derivedMembers, API))
{
// Guards against private members
static if (__traits(compiles, __traits(getMember, API, 
member)))

{
static if (isSomeFunction!(__traits(getMember, API, 
member))
&& !hasUDA!(__traits(getMember, API, member), 
IgnoreUDA)

&& !isSpecialFunction!member)
{
alias overloads = MemberFunctionsTuple!(API, 
member);


foreach (MethodType; overloads)
{
// function dependent code here
}
}
}
}


What's the idiomatic way to refactor / reuse this code fragment?

-- Johannes


The Idiomatic way would be to wrap it inside another template.

In a year or so you won't need to worry about template overhead 
anymore, (if I succeed that is :) )




Deduplicating template reflection code

2017-04-14 Thread Johannes Pfau via Digitalmars-d-learn
I've got this code duplicated in quite some functions:

-
foreach (member; __traits(derivedMembers, API))
{
// Guards against private members
static if (__traits(compiles, __traits(getMember, API, member)))
{
static if (isSomeFunction!(__traits(getMember, API, member))
&& !hasUDA!(__traits(getMember, API, member), IgnoreUDA)
&& !isSpecialFunction!member)
{
alias overloads = MemberFunctionsTuple!(API, member);

foreach (MethodType; overloads)
{
// function dependent code here
}
}
}
}


What's the idiomatic way to refactor / reuse this code fragment?

-- Johannes



Re: Reflection in D

2017-01-28 Thread medhi558 via Digitalmars-d-learn

thank you, the second method works perfectly.

I have one last problem, I start thread and in thread 
Protocol.GetInstance(id) return null while in main thread it 
works.


My class :

class ProtocolMessageManager
{
private static TypeInfo_Class[uint] m_types;

shared static this()
{
foreach(mod; ModuleInfo)
{
foreach(TypeInfo_Class lc; mod.localClasses)
{
if(lc.base is typeid(NetworkMessage))
{
NetworkMessage c = cast(NetworkMessage)lc.create();
ProtocolMessageManager.m_types[c.MessageId] = lc;
}
}
}
   }

   public static NetworkMessage GetInstance(uint id)
   {
   auto v = (id in ProtocolMessageManager.m_types);
   if (v !is null)
	return 
cast(NetworkMessage)ProtocolMessageManager.m_types[id].create();

   else
return null;
}
}


Re: Reflection in D

2017-01-28 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 28 January 2017 at 07:10:27 UTC, medhi558 wrote:

I have a last question, currently i use :
if(lc.name.indexOf("protocol.messages") != -1)


If they're all in the same module, you can also use the compile 
time reflection to scan the module for classes. That's


foreach(memberName; __traits(allMembers, mixin(__MODULE__)))
  static if(is(__traits(getMember, mixin(__MODULE__), memberName) 
: NetworkMessage) {

   if(memberName == runtime_string_of_class_name) {
  auto msg = new __traits(getMember, mixin(__MODULE__), 
memberName);

   // populate msg
   }
   }


Or something like that. The compile time stuff works well when 
everything is in a shared module.


If not, the runtime stuff has methods `base` and `interfaces` you 
can scan for your class. So like


foreach(c; mod.localClasses
  if(c.base is typeid(NetworkMessage) {
  // work with it
  }


Notice it is typeid for runtime, typeof at compile time, and this 
only gets direct children of NetworkMessage (though you could 
walk up the parent list to check more).




Re: Reflection in D

2017-01-28 Thread medhi558 via Digitalmars-d-learn

On Saturday, 28 January 2017 at 09:05:13 UTC, rumbu wrote:
As long as your class has a default constructor, you can use 
directly Object.factory(id):


public static NetworkMessage GetInstance(string id)
{
  return cast(NetworkMessage)(Object.factory(id));
}


It isn't possible. My function when I receive data :

private void ReceivedData(char[] buffer)
{
BinaryReader reader = new BinaryReader();
uint id = reader.ReadUInt();
uint length = reader.ReadInt();
if(length > reader.Available.length)
{
   //waiting for the rest
   return;
}

NetworkMessage message = 
ProtocolMessageManager.GetInstance(id);

message.Deserialize();

//.
}



Re: Reflection in D

2017-01-28 Thread medhi558 via Digitalmars-d-learn

abstract class NetworkMessage
{
uint MessageId;
//
}

override class QueueStatusUpdateMessage : NetworkMessage
{
uint MessageId = 1;
//
}

override class Message2 : NetworkMessage
{
uint MessageId = 2;
//
}

override class Message3 : NetworkMessage
{
uint MessageId = 3;
//
}

And I would like to retrieve all the classes that are based on 
NetworkMessage.


class ProtocolMessageManager
{
private static TypeInfo_Class[uint] m_types;

public static void Init()
{
foreach(mod; ModuleInfo)
{
foreach(TypeInfo_Class lc; mod.localClasses)
{
if() //lc is NetworkMessage so
{
NetworkMessage c = 
cast(NetworkMessage)lc.create();

ProtocolMessageManager.m_types[c.MessageId] = lc;
}
}

}
}

public static NetworkMessage GetInstance(string id)
{
auto v = (id in ProtocolMessageManager.m_types);
if (v !is null)
	 return 
cast(NetworkMessage)ProtocolMessageManager.m_types[id].create();

else
 return null;
}
}



Re: Reflection in D

2017-01-28 Thread rumbu via Digitalmars-d-learn

On Saturday, 28 January 2017 at 07:03:51 UTC, medhi558 wrote:


public static NetworkMessage GetInstance(string id)
{
auto v = (id in ProtocolMessageManager.m_types);
if (v !is null)
	 return 
cast(NetworkMessage)ProtocolMessageManager.m_types[id].create();

else
 return null;
}
}


As long as your class has a default constructor, you can use 
directly Object.factory(id):


public static NetworkMessage GetInstance(string id)
{
  return cast(NetworkMessage)(Object.factory(id));
}


Re: Reflection in D

2017-01-28 Thread rumbu via Digitalmars-d-learn

On Saturday, 28 January 2017 at 08:18:15 UTC, medhi558 wrote:

On Saturday, 28 January 2017 at 07:39:51 UTC, rumbu wrote:

On Saturday, 28 January 2017 at 07:10:27 UTC, medhi558 wrote:

I have a last question, currently i use :
if(lc.name.indexOf("protocol.messages") != -1)

To know if the class is a NetworkMessage, Would be possible 
to do this


if(lc is NetworkMessage)


Sorry for my English, i speak french.


if (auto nm = cast(NetworkMessage)lc)
{
  //do something with nm
}


It doesn't work because lc is TypeInfo_Class


In this case:

if (lc == typeid(NetworkMessage))


Re: Reflection in D

2017-01-28 Thread medhi558 via Digitalmars-d-learn

On Saturday, 28 January 2017 at 07:39:51 UTC, rumbu wrote:

On Saturday, 28 January 2017 at 07:10:27 UTC, medhi558 wrote:

I have a last question, currently i use :
if(lc.name.indexOf("protocol.messages") != -1)

To know if the class is a NetworkMessage, Would be possible to 
do this


if(lc is NetworkMessage)


Sorry for my English, i speak french.


if (auto nm = cast(NetworkMessage)lc)
{
  //do something with nm
}


It doesn't work because lc is TypeInfo_Class


Re: Reflection in D

2017-01-27 Thread rumbu via Digitalmars-d-learn

On Saturday, 28 January 2017 at 07:10:27 UTC, medhi558 wrote:

I have a last question, currently i use :
if(lc.name.indexOf("protocol.messages") != -1)

To know if the class is a NetworkMessage, Would be possible to 
do this


if(lc is NetworkMessage)


Sorry for my English, i speak french.


if (auto nm = cast(NetworkMessage)lc)
{
  //do something with nm
}




Re: Reflection in D

2017-01-27 Thread medhi558 via Digitalmars-d-learn

I have a last question, currently i use :
if(lc.name.indexOf("protocol.messages") != -1)

To know if the class is a NetworkMessage, Would be possible to do 
this


if(lc is NetworkMessage)


Sorry for my English, i speak french.


Re: Reflection in D

2017-01-27 Thread medhi558 via Digitalmars-d-learn

I develop a game server. Currently I use a switch :

import protocol.messages.connection.Message1;
import protocol.messages.connection.Message2;
import protocol.messages.queues.Message3;
import ..

import protocol.messages.NetworkMessage;

class ProtocolMessageManager
{
public static NetworkMessage GetInstance(uint id)
{
  switch(id)
  {
 case Message1.Id:
 return new Message1();
 case Message2.Id:
 return new Message2();
 .

 default:
  return null;
  }
}
}

what I want to do :

import protocol.messages.NetworkMessage;

class ProtocolMessageManager
{
private static TypeInfo_Class[uint] m_types;

public static void Init()
{
foreach(mod; ModuleInfo)
{
foreach(TypeInfo_Class lc; mod.localClasses)
{
if(lc.name.indexOf("protocol.messages") != -1)
{
NetworkMessage c = 
cast(NetworkMessage)lc.create();

ProtocolMessageManager.m_types[c.MessageId] = lc;
}
}

}
}

public static NetworkMessage GetInstance(string id)
{
auto v = (id in ProtocolMessageManager.m_types);
if (v !is null)
	 return 
cast(NetworkMessage)ProtocolMessageManager.m_types[id].create();

else
 return null;
}
}


Re: Reflection in D

2017-01-27 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 27 January 2017 at 21:02:13 UTC, medhi558 wrote:
Hello, I would like to know if it is possible to recover all 
classes in the project in D.


Yes, `foreach(mod; ModuleInfo) foreach(lc; mod.localClasses)`... 
but why do you want it? That facility is kinda limited in doing 
many things with.


Reflection in D

2017-01-27 Thread medhi558 via Digitalmars-d-learn
Hello, I would like to know if it is possible to recover all 
classes in the project in D.


Example in c# :

Assembly asm = Assembly.GetAssembly(typeof(MyClass));

foreach (Type type in asm.GetTypes())
{
}


Re: Reflection: Order of fields guaranteed?

2016-10-22 Thread Michael Coulombe via Digitalmars-d-learn

On Friday, 21 October 2016 at 01:51:44 UTC, Stefan Koch wrote:
On Friday, 21 October 2016 at 01:34:44 UTC, Nick Sabalausky 
wrote:
When using reflection to obtain the fields of a class/struct, 
is there any guarantee that the order is the same as the order 
the fields are defined?


Yes they should always come in lexical order.


For classes, the spec disagrees, even though it might be true 
using current compilers.


https://dlang.org/spec/class.html#fields

"The D compiler is free to rearrange the order of fields in a 
class to optimally pack them in an implementation-defined manner. 
... Explicit control of field layout is provided by struct/union 
types, not classes."


Re: Reflection: Order of fields guaranteed?

2016-10-21 Thread Stefan Koch via Digitalmars-d-learn

On Friday, 21 October 2016 at 01:34:44 UTC, Nick Sabalausky wrote:
When using reflection to obtain the fields of a class/struct, 
is there any guarantee that the order is the same as the order 
the fields are defined?


Yes they should always come in lexical order.



Reflection: Order of fields guaranteed?

2016-10-21 Thread Nick Sabalausky via Digitalmars-d-learn
When using reflection to obtain the fields of a class/struct, is there 
any guarantee that the order is the same as the order the fields are 
defined?


Re: Probably a real simple compile-time reflection question?

2016-07-09 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 9 July 2016 at 21:12:24 UTC, WhatMeWorry wrote:

foreach( i, str; myClassMembers)


What are you doing to get myClassMembers?

If it is __traits(allMembers), it just gives you the *names* of 
the members. To get the actual thing, you then do 
__traits(getMember, object, str) and can check the type of that.


Also, is there a way to get __traits(allMembers  to work 
recursively?  Say, with struct containing structs.


You can always just call it recursively once you get the member :)


Probably a real simple compile-time reflection question?

2016-07-09 Thread WhatMeWorry via Digitalmars-d-learn


class C
{
this(){ _i = 0; _j = 0; }
void setVar(int i) { _i = i; }
int getVar() { return _i; }
int _i;
int _j;
}

writeln("C");
foreach( i, str; myClassMembers)
{
writeln("member ", i, " = ", str);
TypeInfo ti = typeid(str);
writeln("type id is ", ti);
writeln("type is ", typeof(str).stringof);
}


C
member 0 = __ctor
type id is immutable(char)[]
type is string
member 1 = _i
type id is immutable(char)[]
type is string
member 2 = setVar
type id is immutable(char)[]
type is string
member 3 = getVar
type id is immutable(char)[]
type is string
 . . .
the same all the way through the class

I'm trying to get at least the type int for the _i member?  Also, 
is there a way to get __traits(allMembers  to work recursively?  
Say, with struct containing structs.


Thanks,
kyle






Request for feedback on reflection based module

2016-01-18 Thread Ross Harrison via Digitalmars-d-learn
Hi I'm trying out D and wanted to try some features cpp doesn't 
have yet. So I put together a small json parsing, generating 
looking based on reflection. Is there anything wrong with how I'm 
working with it in the module?

https://github.com/rharriso/JSONInflater.d

Thanks in advance


package reflection

2014-06-22 Thread sigod via Digitalmars-d-learn
In the video Case Studies In Simplifying Code With Compile-Time 
Reflection [was pointed out][0] that it is possible to reflect 
on imported packages.


So, I tried:

reflection.d:
```
import std.stdio;

import test.module1;
import test.module2;

void main() {
foreach (m; __traits(allMembers, mixin(__MODULE__))) {
writeln(m);
}

writeln(--);

foreach (m; __traits(allMembers, test)) {
writeln(m);
}
}
```

test/module1.d:
```
module test.module1;

void module_1() {}
```

test/module2.d:
```
module test.module2;

void module_2() {}
```

It produces:
```
$ rdmd reflection.d
object
std
test
main
--
object
module_1
```

As you see `module_2` wasn't listed. If I change order of import 
declarations `module_2` will be listed instead of `module_1`.


I also tried to create `test/package.d` and publicly import other 
modules through it, but it behave in the same way.


So, how to reflect on imported packages?

[0]: http://youtu.be/xpImt14KTdc?t=42m26s


Re: package reflection

2014-06-22 Thread Shammah Chancellor via Digitalmars-d-learn

On 2014-06-22 14:11:58 +, sigod said:

In the video Case Studies In Simplifying Code With Compile-Time 
Reflection [was pointed out][0] that it is possible to reflect on 
imported packages.


So, I tried:

reflection.d:
```
import std.stdio;

import test.module1;
import test.module2;

void main() {
foreach (m; __traits(allMembers, mixin(__MODULE__))) {
writeln(m);
}

writeln(--);

foreach (m; __traits(allMembers, test)) {
writeln(m);
}
}
```

test/module1.d:
```
module test.module1;

void module_1() {}
```

test/module2.d:
```
module test.module2;

void module_2() {}
```

It produces:
```
$ rdmd reflection.d
object
std
test
main
--
object
module_1
```

As you see `module_2` wasn't listed. If I change order of import 
declarations `module_2` will be listed instead of `module_1`.


I also tried to create `test/package.d` and publicly import other 
modules through it, but it behave in the same way.


So, how to reflect on imported packages?

[0]: http://youtu.be/xpImt14KTdc?t=42m26s


This is very frustrating indeed, and I have an open bug request about 
it. Please bump it so it gets some attention:


https://issues.dlang.org/show_bug.cgi?id=11595

-Shammah



Class Data Members Name Reflection

2014-06-10 Thread Nordlöw
Is there a way to iterate over the symbolic names of the data 
members of a class instance?


I'm currently using .tupleof to get its values (and in turn 
types) to implement   pretty printing to multiple backends 
(currently testing HTML) using as much of D's compile time 
reflection as possible:


https://github.com/nordlow/justd/blob/master/pprint.d

I've currently defined mappings from InputRanges of Aggregates 
(tuples, structs, and classes) to HTML tables where


- the aggregate members are mapped to table columns (and their 
types in turn two column headers) and

- range elements to rows

and I would like to perfect the output by also propagating the 
member names to the column headings.


I'm aware of __traits(allMembers, Type) but those return more 
than .tupleof does.


Help please.


Re: Class Data Members Name Reflection

2014-06-10 Thread Adam D. Ruppe via Digitalmars-d-learn
Two options: do allMembers and filter it out to only be data 
members, or do some slicing of tupleof.stringof:


S s;
foreach(idx, member; s.tupleof) {
   writeln(Name: , s.tupleof[idx].stringof[2..$]);
}


The tupleof[idx] inside the loop is important instead of just 
using member because then you get the name, then the slicing is 
because you get:


s.foo

for example, and you want to slice off the s. to leave just the 
name.


Re: Class Data Members Name Reflection

2014-06-10 Thread Nordlöw

On Tuesday, 10 June 2014 at 16:13:31 UTC, Adam D. Ruppe wrote:
Two options: do allMembers and filter it out to only be data 
members, or do some slicing of tupleof.stringof:


What trait should I use to filter out data members?


S s;
foreach(idx, member; s.tupleof) {
   writeln(Name: , s.tupleof[idx].stringof[2..$]);
}


Ok.

I tried

foreach (ix, memb; arg.args[0].front.tupleof)
{
import std.stdio: writeln;
writeln(arg.args[0].front.tupleof[ix].stringof);
}

Almost there...except that the print seems to verbose and bit 
funny:


ref FKind __tup4778 = front(arg._args_field_0);
 , __tup4778.kindName
ref FKind __tup4779 = front(arg._args_field_0);
 , __tup4779.description
ref FKind __tup4780 = front(arg._args_field_0);
 , __tup4780.wikiURL
ref FKind __tup4781 = front(arg._args_field_0);

Did I do something wrong?


Re: Class Data Members Name Reflection

2014-06-10 Thread Adam D. Ruppe via Digitalmars-d-learn

On Tuesday, 10 June 2014 at 16:30:52 UTC, Nordlöw wrote:

What trait should I use to filter out data members?


No trait, more like an is thing to see if the thing has an init. 
I think


static if(is(typeof(__traits(getMember, Thing, name).init)) { }

will do it. (BTW the sample chapter of my book talks about 
reflection, I think I talked about some of this in there: 
http://www.packtpub.com/discover-advantages-of-programming-in-d-cookbook/book 
)



foreach (ix, memb; arg.args[0].front.tupleof)


Eeek, I actually used s for a reason there - it gives you a 
simple name that is easily repeated and filtered. The nasty 
string you're seeing is the name of a compiler-generated 
temporary variable in the foreach.


That said, your field names are in there at the end, so another 
option would be to run it through lastIndexOf(.) and then slice 
to that.


So it works backward to the dot and slices off the rest of the 
string.


string s = arg.args[0].front.tupleof[idx].stringof;
auto dotIndex = s.lastIndexOf(.);
assert(dotIndex = 0); // it ought to be there anyway
auto name = s[dotIndex + 1 .. $]; // slice off the temp name, 
whatever it is




Re: Class Data Members Name Reflection

2014-06-10 Thread Dicebot via Digitalmars-d-learn

On Tuesday, 10 June 2014 at 16:10:09 UTC, Nordlöw wrote:
Is there a way to iterate over the symbolic names of the data 
members of a class instance?


I'm currently using .tupleof to get its values (and in turn 
types) to implement   pretty printing to multiple backends 
(currently testing HTML) using as much of D's compile time 
reflection as possible:


https://github.com/nordlow/justd/blob/master/pprint.d

I've currently defined mappings from InputRanges of Aggregates 
(tuples, structs, and classes) to HTML tables where


- the aggregate members are mapped to table columns (and their 
types in turn two column headers) and

- range elements to rows

and I would like to perfect the output by also propagating the 
member names to the column headings.


I'm aware of __traits(allMembers, Type) but those return more 
than .tupleof does.


Help please.


I am not sure I understand the question. Does this help?

struct A
{
int x;
double y;
}

void main()
{
foreach (idx, elem; A.init.tupleof)
{
pragma(msg, __traits(identifier, A.tupleof[idx]));
}
}

// output:
// x
// y


Re: Class Data Members Name Reflection

2014-06-10 Thread Nordlöw

I am not sure I understand the question. Does this help?

struct A
{
int x;
double y;
}

void main()
{
foreach (idx, elem; A.init.tupleof)
{
pragma(msg, __traits(identifier, A.tupleof[idx]));
}
}

// output:
// x
// y


Exactly what I wanted!

BTW: Can DMD serve use file and line location of user defined 
type aswell?


Thx!


Re: Class Data Members Name Reflection

2014-06-10 Thread Nordlöw
BTW: Can DMD serve use file and line location of user defined 
type aswell?


Thx!


Correction: I mean serve *us*


Re: Class Data Members Name Reflection

2014-06-10 Thread Nordlöw

On Tuesday, 10 June 2014 at 17:29:35 UTC, Dicebot wrote:

On Tuesday, 10 June 2014 at 16:10:09 UTC, Nordlöw wrote:
Is there a way to iterate over the symbolic names of the data 
members of a class instance?


I'm currently using .tupleof to get its values (and in turn 
types) to implement   pretty printing to multiple backends 
(currently testing HTML) using as much of D's compile time 
reflection as possible:


https://github.com/nordlow/justd/blob/master/pprint.d

I've currently defined mappings from InputRanges of Aggregates 
(tuples, structs, and classes) to HTML tables where


- the aggregate members are mapped to table columns (and their 
types in turn two column headers) and

- range elements to rows

and I would like to perfect the output by also propagating the 
member names to the column headings.


I'm aware of __traits(allMembers, Type) but those return more 
than .tupleof does.


Help please.


I am not sure I understand the question. Does this help?

struct A
{
int x;
double y;
}

void main()
{
foreach (idx, elem; A.init.tupleof)
{
pragma(msg, __traits(identifier, A.tupleof[idx]));
}
}

// output:
// x
// y


Notice that A.init.tupleof segfaults for classes so that is _not_ 
an adviced solution in a generic solution!


But fortunately I always have an instance, say a, of A available 
in the pprint functions so I just use a.tupleof instead! Now it 
works!


I'll update pprint.d later today! I'll further extract away the 
dumb dependencies for pprint.d in the upcoming days so it can be 
reused later on.


Thanks you all!


Re: Class Data Members Name Reflection

2014-06-10 Thread Kapps via Digitalmars-d-learn

On Tuesday, 10 June 2014 at 16:13:31 UTC, Adam D. Ruppe wrote:
Two options: do allMembers and filter it out to only be data 
members, or do some slicing of tupleof.stringof:


S s;
foreach(idx, member; s.tupleof) {
   writeln(Name: , s.tupleof[idx].stringof[2..$]);
}


The tupleof[idx] inside the loop is important instead of just 
using member because then you get the name, then the slicing is 
because you get:


s.foo

for example, and you want to slice off the s. to leave just 
the name.


You may not want to use stringof for this, because stringof is 
explicitly defined as being able to change across versions, and 
no actual format is defined. Instead use __traits(identifier, 
s.tupleof[idx]).


Also note that .tupleof will not return static fields.


Re: Class Data Members Name Reflection

2014-06-10 Thread Kapps via Digitalmars-d-learn

On Tuesday, 10 June 2014 at 20:01:37 UTC, Nordlöw wrote:


Notice that A.init.tupleof segfaults for classes so that is 
_not_ an adviced solution in a generic solution!




There's no need to use .init:

import std.stdio;

struct Foo {
int a, b;
}

void main() {
writeln(__traits(identifier, Foo.tupleof[0]));
}


DMD fail when using both reflection and UDA

2014-06-01 Thread bioinfornatics via Digitalmars-d-learn

DMD (dmdfe 2.066) fail when i use UDA which store a delegate


code below works if i remove @section UDA otheswise it give this
error:

dmd: statement.c:714: ErrorStatement::ErrorStatement(): Assertion
`global.gaggedErrors || global.errors' failed.


is a bug  ?



--- CODE also on dpaste http://dpaste.dzfl.pl/3a3d660bd3bc

import std.stdio;
import std.typecons : Tuple;
import std.typetuple : Filter;


struct attribute{}

@attribute
struct section( alias start, alias end)
{
 alias checkStart = start;
 alias checkEnd = end;
}

template hasSection(T)
{
 static bool helper()
 {
 foreach(memberName; __traits(allMembers, T))
 {
 foreach(attr; __traits(getAttributes,
__traits(getMember, T, memberName)))
 {
 static if(is(attr == Section))
 return true;
 }
 }
 return false;
 }

 enum hasSection = helper();
}

struct Data{
 @section!( ( words ) =  words[0] == '@' , (
words ) =  words[0] == '\n' )
 string a;
 @section!( ( words ) =  words[0]  63  words[0] 115  , (
words ) =  words[0] == '\n' )
 string b;
 @section!( ( words ) =  words[0] == '+' , (
words ) =  words[0] == '\n' )
 string c;
}

template toTuple(T){
 static string maker(){
 string statement = alias toTuple = Tuple!(;
 foreach(const memberName; __traits(allMembers, T)){
 //~ mixin(`alias f = Filter!(hasSection,
__traits(getAttributes, T.` ~ memberName ~ `));`);
 statement ~=  typeof(__traits(getMember, T,
memberName)).stringof  ~ ,\ ~ memberName ~ \,  ;
 }
 statement = statement[0..$-2] ~ ) ; ; // $-2 to remove
extra comma
 return statement;
 }
 mixin( maker() );
}


void main()
{
 alias A = toTuple!Data;
 A a;
 a[0] = 1;
 a.x = 1;
}


Re: DMD fail when using both reflection and UDA

2014-06-01 Thread bioinfornatics via Digitalmars-d-learn

On Sunday, 1 June 2014 at 16:02:47 UTC, bioinfornatics wrote:

DMD (dmdfe 2.066) fail when i use UDA which store a delegate


code below works if i remove @section UDA otheswise it give this
error:

dmd: statement.c:714: ErrorStatement::ErrorStatement(): 
Assertion

`global.gaggedErrors || global.errors' failed.


is a bug  ?



--- CODE also on dpaste http://dpaste.dzfl.pl/3a3d660bd3bc

import std.stdio;
import std.typecons : Tuple;
import std.typetuple : Filter;


struct attribute{}

@attribute
struct section( alias start, alias end)
{
 alias checkStart = start;
 alias checkEnd = end;
}

template hasSection(T)
{
 static bool helper()
 {
 foreach(memberName; __traits(allMembers, T))
 {
 foreach(attr; __traits(getAttributes,
__traits(getMember, T, memberName)))
 {
 static if(is(attr == Section))
 return true;
 }
 }
 return false;
 }

 enum hasSection = helper();
}

struct Data{
 @section!( ( words ) =  words[0] == '@' , 
(

words ) =  words[0] == '\n' )
 string a;
 @section!( ( words ) =  words[0]  63  words[0] 115  , 
(

words ) =  words[0] == '\n' )
 string b;
 @section!( ( words ) =  words[0] == '+' , 
(

words ) =  words[0] == '\n' )
 string c;
}

template toTuple(T){
 static string maker(){
 string statement = alias toTuple = Tuple!(;
 foreach(const memberName; __traits(allMembers, T)){
 //~ mixin(`alias f = Filter!(hasSection,
__traits(getAttributes, T.` ~ memberName ~ `));`);
 statement ~=  typeof(__traits(getMember, T,
memberName)).stringof  ~ ,\ ~ memberName ~ \,  ;
 }
 statement = statement[0..$-2] ~ ) ; ; // $-2 to 
remove

extra comma
 return statement;
 }
 mixin( maker() );
}


void main()
{
 alias A = toTuple!Data;
 A a;
 a[0] = 1;
 a.x = 1;
}



ok it seem problem from my code a type string i need to
understand why


Re: DMD fail when using both reflection and UDA

2014-06-01 Thread bioinfornatics via Digitalmars-d-learn

stupid me bug was at the end

a[0] = 1;
  become
  a[0] = 1;

but error error was so stnange to me i though that was a bug


Re: DMD fail when using both reflection and UDA

2014-06-01 Thread Philippe Sigaud via Digitalmars-d-learn
In any case, it's an internal compiler error, so it's a bug. Users
should never see ICEs.
Could you please report it, with the entire error message?


Re: DMD fail when using both reflection and UDA

2014-06-01 Thread bioinfornatics via Digitalmars-d-learn

On Sunday, 1 June 2014 at 16:18:45 UTC, Philippe Sigaud via
Digitalmars-d-learn wrote:
In any case, it's an internal compiler error, so it's a bug. 
Users

should never see ICEs.
Could you please report it, with the entire error message?


Ok thanks is don at https://issues.dlang.org/show_bug.cgi?id=12838


Re: templates, enums, CT reflection: compiler bug or not?

2014-04-06 Thread captaindet

no one any ideas?

well, i filed two bug reports for now:
https://d.puremagic.com/issues/show_bug.cgi?id=12532
https://d.puremagic.com/issues/show_bug.cgi?id=12533


Re: Does D have reflection?

2014-04-05 Thread Adam D. Ruppe

On Sunday, 6 April 2014 at 02:25:32 UTC, dnspies wrote:
For instance, could I write a generic function to reconstruct 
any object of any type from a JSON object?


Yes, you can use __traits(allMembers) at compile time to build a 
runtime function that does the setting. .tupleof can do it too, 
which is what I used in the fromUrlParam function in my web.d 
that populates a struct from an associative array of runtime 
strings:

https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/web.d#L2507


templates, enums, CT reflection: compiler bug or not?

2014-04-04 Thread captaindet

i stumbled upon something strange while wondering around meta/codegen-lands. it 
took me almost a week to reduce it to the following test case. i have no clue 
what is going on, whether i have entered bug territory or just encountered my 
own limitations

mind you, i have 2 issues with the code:
 
(1) that my template, which uses  __traits(compiles, ...), under certain circumstances (aka 'if things are getting complicated') fails to see symbols that one could argue are valid in this scope. (annoying maybe, but not my main problem)


(2) the strange compiler error i get when using the template on itself, but 
only if it is not the first time that the instantiation is used. this is my 
real issue cause i don't know how to work around this. during my attempts to 
reduce this, starting from much more complicated code, i encountered all sorts 
of errors, including ICE and __error stuff.

so am i being stupid or is it a compiler bug?

cheers,
det

===CODE===

module demo;

template valid(string mem){
pragma(msg, instantiation of valid with: ~mem);
static if( !__traits( compiles, mixin(mem) ) ){
enum valid = false;
}else{
enum valid =  true;
 }
}

enum ok = valid!foo;
pragma(msg, ok );   // - true // fine, recognizes 'foo' in module 
scope

enum works = valid!fails;
pragma(msg, works );// - false // problematic, fails to see 
'fails' in module scope

enum dummy = valid!fails;
pragma(msg, dummy );// - false // same behavior, as long as you 
are not testing yourself

enum fails = valid!fails; // Error: variable demo.fails had semantic 
errors when compiling
// NOTE: if you comment out the first two usages of valid!fails, it will work 
here,
// although it will result in false

//  pragma(msg, fails );

enum foo = 42;

void main(){}


Re: reflection over templates

2014-03-19 Thread Dicebot
On Wednesday, 19 March 2014 at 16:18:17 UTC, Andrej Mitrovic 
wrote:

And after we determine it is a template, can we extract the
required arguments list like we can with a regular function at
all?


Well there's TemplateArgsOf for *instantiations*, but I'm not 
sure how
one would do it with non-instantiations. In particular how 
would we
create a tuple of template parameter types where one of the 
parameters

was an alias?

E.g.:

template Foo(int, alias X);

alias Args = TypeTuple!(int, ???);

There is no alias type you could use in this case.


One can use value instead of a type, like alias.


Re: reflection over templates

2014-03-19 Thread Dicebot

As a workaround one can use set of relevant trait checks:
1) type is void
2) is not a variable or callable
3) .stringof fits NAME(ARGS) pattern


Re: reflection over templates

2014-03-19 Thread Dicebot
Wait just a bit more 
https://github.com/D-Programming-Language/dmd/pull/3380 :)


Re: reflection over templates

2014-03-19 Thread Adam D. Ruppe

On Wednesday, 19 March 2014 at 16:10:52 UTC, Dicebot wrote:
Wait just a bit more 
https://github.com/D-Programming-Language/dmd/pull/3380 :)


megarox. Make it so.


reflection over templates

2014-03-19 Thread Adam D. Ruppe

Given:

template Foo(string T) { enum Foo = to!int(T); }

(or anything else, really)

Is there anything we can do with static if to identify it as a 
template?


I tried:

static if(is(Foo == template)) {} // nope, basic type expected, 
not template


Note that is(typeof(Foo) == function) {} is how we check for 
regular functions.



static if(is(typeof(Foo) == template)) {} // nope


In fact, typeof(Foo) == void... is that something we can use?


I know we can break down a template instantiation with one of the 
arcane is expressions, but I don't have that here, I just want to 
identify the template Foo as a template.


This is in the context of doing __traits(allMembers) over a 
module and trying to categorize every member.



Checking for a void type seems to be the closest I've gotten, but 
that seems awfully strange. I guess other variables can't be 
declared with type void, so maybe that is a unique 
differentiator, but still, idk about it.



And after we determine it is a template, can we extract the 
required arguments list like we can with a regular function at 
all?


Re: reflection over templates

2014-03-19 Thread Andrej Mitrovic
On 3/19/14, Adam D. Ruppe destructiona...@gmail.com wrote:
 Is there anything we can do with static if to identify it as a
 template?

https://github.com/D-Programming-Language/dmd/pull/3380

 And after we determine it is a template, can we extract the
 required arguments list like we can with a regular function at
 all?

Well there's TemplateArgsOf for *instantiations*, but I'm not sure how
one would do it with non-instantiations. In particular how would we
create a tuple of template parameter types where one of the parameters
was an alias?

E.g.:

template Foo(int, alias X);

alias Args = TypeTuple!(int, ???);

There is no alias type you could use in this case.


Re: reflection over templates

2014-03-19 Thread simendsjo

On 03/19/2014 05:34 PM, Adam D. Ruppe wrote:

On Wednesday, 19 March 2014 at 16:10:52 UTC, Dicebot wrote:

Wait just a bit more
https://github.com/D-Programming-Language/dmd/pull/3380 :)


megarox. Make it so.


Nice. I have some ugly hacks that's probably full of bugs for this (look 
at the bottom):


template isLValue(T)
{
enum isLValue = false;
}
/// ditto
template isLValue(alias T)
{
enum isLValue = !isType!T  isAddressable!T  __traits(compiles, 
{ Unqual!(TypeOf!T) t = TypeOf!(T).init; });

}
/// ditto
template isRValue(T)
{
enum isRValue = false;
}
/// ditto
template isRValue(alias T)
{
static if(isType!T)
enum isRValue = false;
else
enum isRValue = __traits(compiles, { typeof(T) t = T; })  
!isAddressable!T;

}

template isValue(T)
{
enum isValue = false;
}
/// ditto
template isValue(alias T)
{
enum isValue = isLValue!T || isRValue!T;
}
/// ditto
template isType(T)
{
enum isType = is(T);
}
/// ditto
template isType(alias T)
{
enum isType = is(T) || isCallable!T;
}
template isTemplate(T)
{
enum isTemplate = !(isValue!T || isType!T);
}
template isTemplate(alias T)
{
enum isTemplate = !(isValue!T || isType!T);
}



DLL's reflection and Exceptions

2013-12-28 Thread TheFlyingFiddle

Hello everyone!

I'm currently working on a run-time reflection module. The intent 
of this module is to simplify the process of loading functions / 
classes / structs from DLL's loaded at run-time.


It works something like this ATM:

//In pluggin.d (A dll module)

void foo() { ... }
class Bar  { ... }
struct Baz { ... }

... more members

At the end of the file i have a function like this

export extern(C) MetaAssembly getMetaAssembly()
{
   //Tuple of filters to only load relevant stuff.
   alias filters = standardFilters;
   return AssemblyGenerator!(filters, module1, ..., moduleN).data;
}


//In program.d (A host program)
void main()
{
   auto dll = loadDll(pluggin0.dll);
   MetaAssembly assembly = 
dll.func!(getter_t)(getMetaAssembly)()


   //Use assembly to find some classes
   //construct them and invoke some methods.
   MetaClass c = assembly.
  classes.
  find!(x = x.name == Foo)[0];
   RTObject fooObj = c.constructors[0].create();

   MetaMethod method = c.methods[0];
   method.invoke(fooObj, Hello);
}


AssemblyGenerator!(...) extracts all needed information from the 
modules and stores them in a collection of structs that can be 
used at run-time to do stuff like create instances / set fields / 
check attributes. Normal reflection stuff.


This works fine for normal code flow. However it all falls apart 
as soon as any function located in a DLL throws an exception. If 
an exception is thrown the application freezes, usually visual 
studio crashes with First hand exception: Privileged Instruction 
(some address).


I have hacked my way around this limitation like so:

//pluggin.d

alias exception_handler_t = void function(Throwable) nothrow;
__gshared exception_handler_t exceptionHandler;

//program.d
Throwable t = null;
void exceptionHandler(Throwable thrown) nothrow
{
t = thrown;
}

bool exceptionThrown()
{
   return t !is null;
}

void rethrowException()
{
   DLLException e = new DLLException(t.toString());
   t = null;
   throw e;
}

void main()
{
   auto dll = loadDLL(pluggin0.dll);
   MetaAssembly assembly = 
dll.func!(getter_t)(getMetaAssembly)()	

   auto field = assembly.
staticFields.
find!(x = x.name == exceptionHandler);

   field.set(exceptionHandler)
}

The reflection api wrapps all functions / methods with a try - 
catch that will
call the exceptionHandler if an exception occurs. At the calle 
side (program.a)
after every call it will check if an exception was thrown and if 
so rethrowng it

as a DLLException.

This workaround works, (atleast for now) but i don't like it. It 
complicates the low-level reflection api alot and it only solves 
the problem of calls from program.d to pluggin.d not the other 
way around (unless i wrap them aswell).


So now to the questions.

1. Why can't i throw exceptions over a DLL boundary?
2. Are there any problems with my hack other then the ones 
already stated?

3. Does other workarounds exist?


Thank you for your time!





Re: Is it possible using reflection or similar to extract only public method names from classes?

2013-08-07 Thread Jacob Carlborg

On 2013-08-07 00:57, Marek Janukowicz wrote:


See traits: http://dlang.org/traits.html

Look for: getProtection, getVirtualFunctions, getVirtualMethods.


And allMembers and derivedMembers.

--
/Jacob Carlborg


Re: Is it possible using reflection or similar to extract only public method names from classes?

2013-08-07 Thread Gary Willoughby

On Tuesday, 6 August 2013 at 22:55:49 UTC, Marek Janukowicz wrote:

Gary Willoughby wrote:

Is it possible using reflection or similar to extract only 
public

method names from classes? I'm thinking how i would go about
writing a unit test/mocking framework, investigating how i can
gather information about such things before i manipulate them.


See traits: http://dlang.org/traits.html

Look for: getProtection, getVirtualFunctions, getVirtualMethods.


I thought using __traits(...) was frowned upon?


Re: Is it possible using reflection or similar to extract only public method names from classes?

2013-08-07 Thread Adam D. Ruppe
On Wednesday, 7 August 2013 at 11:47:27 UTC, Gary Willoughby 
wrote:

I thought using __traits(...) was frowned upon?


They want to give them phobos wrappers that might be a little 
prettier, but other than beauty/ugliness there's no reason not to 
use it.


Is it possible using reflection or similar to extract only public method names from classes?

2013-08-06 Thread Gary Willoughby
Is it possible using reflection or similar to extract only public 
method names from classes? I'm thinking how i would go about 
writing a unit test/mocking framework, investigating how i can 
gather information about such things before i manipulate them.


Re: Is it possible using reflection or similar to extract only public method names from classes?

2013-08-06 Thread Marek Janukowicz
Gary Willoughby wrote:

 Is it possible using reflection or similar to extract only public
 method names from classes? I'm thinking how i would go about
 writing a unit test/mocking framework, investigating how i can
 gather information about such things before i manipulate them.

See traits: http://dlang.org/traits.html

Look for: getProtection, getVirtualFunctions, getVirtualMethods.

-- 
Marek Janukowicz


Re: Is it possible using reflection or similar to extract only public method names from classes?

2013-08-06 Thread H. S. Teoh
On Tue, Aug 06, 2013 at 11:41:35PM +0200, Gary Willoughby wrote:
 Is it possible using reflection or similar to extract only public
 method names from classes? I'm thinking how i would go about writing
 a unit test/mocking framework, investigating how i can gather
 information about such things before i manipulate them.

The following code demonstrates how you can do this:

import std.stdio;

class Base {
private int x;
public int y;

this() {}
private void privMethod() {}
public void method() {}
}

class Derived : Base {
public override void method() {}
public void derivedMethod() {}
private void privDerivedMethod() {}
}

void showAllMethods(C)(C obj) {
writeln(All members:);
foreach (field; __traits(allMembers, C)) {
static if (is(typeof(__traits(getMember, obj, field)) T 
== function)) {
auto prot = __traits(getProtection, 
__traits(getMember, obj, field));
writefln(\t(%s) %s, prot, field);
}
}
}

void showDerivedMethods(C)(C obj) {
writeln(\nDerived members:);
foreach (field; __traits(derivedMembers, C)) {
static if (is(typeof(__traits(getMember, obj, field)) T 
== function)) {
auto prot = __traits(getProtection, 
__traits(getMember, obj, field));
writefln(\t(%s) %s, prot, field);
}
}
}

string[] getPublicMethods(C)(C obj) {
string[] methods;
foreach (field; __traits(allMembers, C)) {
static if (is(typeof(__traits(getMember, obj, field)) 
== function) 
__traits(getProtection, 
__traits(getMember, obj, field)) == public)
{
methods ~= field;
}
}
return methods;
}

void main() {
auto d = new Derived();
showAllMethods(d);
showDerivedMethods(d);

writeln(All public methods:);
writeln(getPublicMethods(d));
}


The output is:

All members:
(public) method
(public) derivedMethod
(private) privDerivedMethod
(public) __ctor
(private) privMethod
(public) toString
(public) toHash
(public) opCmp
(public) opEquals
(public) factory

Derived members:
(public) method
(public) derivedMethod
(private) privDerivedMethod
(public) __ctor
All public methods:
[method, derivedMethod, __ctor, toString, toHash, opCmp, 
opEquals, factory]


Hope this helps!


T

-- 
Designer clothes: how to cover less by paying more.


Derived classes? Reflection

2013-04-13 Thread Tofu Ninja
Currently is there a way to get all of the subclasses of a class 
at compile time?
It seems like something that should be possible using traits but 
I can't seems to see how.


Something like

class A{...}
class B:A{...}
class C:A{...}

...

foreach(auto t ; getsubclass(A))
{
   ...
}

Any help would be grateful.
Tofu


Re: Derived classes? Reflection

2013-04-13 Thread Andrej Mitrovic
On 4/13/13, Tofu Ninja emmo...@purdue.edu wrote:
 Currently is there a way to get all of the subclasses of a class
 at compile time?

There might be things like using .moduleinfo and traversing imports to
find all classes, but I think separate compilation makes this
unreliable.

There is however BaseClassTuple in std.traits, so you can pass a leaf
class to get the class hierarchy.


Re: Derived classes? Reflection

2013-04-13 Thread Namespace

On Saturday, 13 April 2013 at 16:16:03 UTC, Tofu Ninja wrote:
Currently is there a way to get all of the subclasses of a 
class at compile time?
It seems like something that should be possible using traits 
but I can't seems to see how.


Something like

class A{...}
class B:A{...}
class C:A{...}

...

foreach(auto t ; getsubclass(A))
{
   ...
}

Any help would be grateful.
Tofu


Maybe this is helpfully:
http://forum.dlang.org/thread/scgjnudclnwlbdqqd...@forum.dlang.org


Re: Derived classes? Reflection

2013-04-13 Thread Tofu Ninja

Maybe this is helpfully:
http://forum.dlang.org/thread/scgjnudclnwlbdqqd...@forum.dlang.org


Oddly enough, I found that at about the same time you posted it.


Re: Derived classes? Reflection

2013-04-13 Thread Tofu Ninja

On Saturday, 13 April 2013 at 17:45:12 UTC, Tofu Ninja wrote:

Maybe this is helpfully:
http://forum.dlang.org/thread/scgjnudclnwlbdqqd...@forum.dlang.org


Oddly enough, I found that at about the same time you posted it.


Sadly this does not provide a compile time solution, only runtime.


Re: question with compile-time reflection

2013-03-10 Thread Rob T

template NDimensionalArrayType(T,alias size)

I'm wondering what alias size does? I can't find that form 
documented anywhere, but it seems to be valid.


Thanks.

--rt


Re: question with compile-time reflection

2013-03-10 Thread Zhenya
And since alias can represent any symbol,i think that it's 
correct usage.




Re: question with compile-time reflection

2013-03-10 Thread Zhenya

On Monday, 11 March 2013 at 00:10:46 UTC, Rob T wrote:

template NDimensionalArrayType(T,alias size)

I'm wondering what alias size does? I can't find that form 
documented anywhere, but it seems to be valid.


Thanks.

--rt


It's just a little hack for known bug - only string and integer 
value can be passed into template.
size is array,and it's really size of n-dimensional array,every 
element matches

its dimension.


Re: question with compile-time reflection

2013-03-10 Thread anonymous

On Monday, 11 March 2013 at 00:10:46 UTC, Rob T wrote:

template NDimensionalArrayType(T,alias size)

I'm wondering what alias size does? I can't find that form 
documented anywhere, but it seems to be valid.


http://dlang.org/template.html#TemplateAliasParameter


Re: question with compile-time reflection

2013-03-10 Thread Rob T

On Monday, 11 March 2013 at 00:26:25 UTC, anonymous wrote:

On Monday, 11 March 2013 at 00:10:46 UTC, Rob T wrote:

template NDimensionalArrayType(T,alias size)

I'm wondering what alias size does? I can't find that form 
documented anywhere, but it seems to be valid.


http://dlang.org/template.html#TemplateAliasParameter


I actually read that page, but somehow missed this description or 
more likely did not understand what it meant. I think I could 
spend 10 years reading up on D and still not fully know 
everything about it.


--rt


question with compile-time reflection

2013-03-09 Thread Zhenya

Hi!

this code fails with message:NDimensionalArray.doIndex(Array) if 
(is(Array _ : NDimensionalArrayType!(T,s),const(int[]) s)) cannot 
deduce template function from argument types 
!()(int[2u][2u],const(int[]))


Tell me please,am I wrong?
And if yes,what should I change to make it work?

template NDimensionalArrayType(T,alias size)
if(is(typeof(size) _ : const int[])  size.length  0)
{
static if(size.length  1)
		alias NDimensionalArrayType!(T,size[1..$])[size[0]] 
NDimensionalArrayType;

else
alias T[size[0]] NDimensionalArrayType;
}

struct NDimensionalArray(T,alias size)
{
private NDimensionalArrayType!(T,size) m_array;
static ref T doIndex(Array)(Array array,const int[] index) //HERE
if(is(Array _ : NDimensionalArrayType!(T,s),const int[] s))
{
assert(index.length == s.length);
if(index.length == 1)
return array[index[0]];
else
return doIndex(array[index[0]],index[1..$]);
}
ref T opIndex(const int[] index)
{
return doIndex(m_array,index);
}
alias m_array this;
}

void main()
{
NDimensionalArray!(int,[2,2]) array;
}


Re: question with compile-time reflection

2013-03-09 Thread Rob T

template NDimensionalArrayType(T,alias size)

I think your use of alias size is incorrect.

See http://dlang.org/declaration.html

--rt


Re: question with compile-time reflection

2013-03-09 Thread Ivan Kazmenko
this code fails with message:NDimensionalArray.doIndex(Array) 
if (is(Array _ : NDimensionalArrayType!(T,s),const(int[]) s)) 
cannot deduce template function from argument types 
!()(int[2u][2u],const(int[]))


Tell me please,am I wrong?
And if yes,what should I change to make it work?


I'm no D expert, but here's what I got.

1. One problem is returning the wrong type from doIndex.  When 
the condition if(index.length == 1) is false, the subsequent 
line is still compiled but fails to return a ref T since 
array[index[0]] is an array of T, not a T.


The correct way (and better for performance, too) would be a 
compile-time static if there, like in the code below.  (I don't 
quite get the syntax of the template constraint for doIndex, so 
I've just commented that out for now.)


2. The next problem is that fixed-size arrays obey value 
semantics, so they should be passed by reference and not by value.


Here's what works for me (DMD 2.062):

-
import std.stdio;

template NDimensionalArrayType(T,alias size)
if(is(typeof(size) _ : const int[])  size.length  0)
{
static if(size.length  1)
alias NDimensionalArrayType!(T,size[1..$])[size[0]]
NDimensionalArrayType;
else
alias T[size[0]] NDimensionalArrayType;
}

struct NDimensionalArray(T,alias size)
{
private NDimensionalArrayType!(T,size) m_array;
	static ref T doIndex(Array)(ref Array array,const int[] index) 
//HERE

//  if(is(Array _ : NDimensionalArrayType!(T,s),const int[] s))
{
//  assert(index.length == s.length);
assert(index.length = size.length);
debug {writefln(doIndex (%s, %s = %s),
typeof(array).stringof,
typeof(index).stringof,
index);}
static if(is(Array : T[]))
{
assert(index.length == 1);
return array[index[0]];
}
else
{
assert(index.length  1);
return doIndex(array[index[0]],index[1..$]);
}
}
ref T opIndex(const int[] index)
{
return doIndex(m_array,index);
}
alias m_array this;
}

void main()
{
NDimensionalArray!(int,[5,2]) array;
array[[4,1]] = 1;
assert(array[[4,1]] == 1);
}
-

With the debug mode on, it successfully prints the following:

-
doIndex (int[2u][5u], const(int[]) = [4, 1])
doIndex (int[2u], const(int[]) = [1])
doIndex (int[2u][5u], const(int[]) = [4, 1])
doIndex (int[2u], const(int[]) = [1])
-

On a side note, this still looks like too much effort to do one 
opIndex in terms of performance.  I doubt that any current 
compiler would optimize all that into a simple multiply + 
bounds-check + add loop.


-
Ivan Kazmenko.


Re: question with compile-time reflection

2013-03-09 Thread Zhenya

On Saturday, 9 March 2013 at 23:05:56 UTC, Ivan Kazmenko wrote:
this code fails with message:NDimensionalArray.doIndex(Array) 
if (is(Array _ : NDimensionalArrayType!(T,s),const(int[]) s)) 
cannot deduce template function from argument types 
!()(int[2u][2u],const(int[]))


Tell me please,am I wrong?
And if yes,what should I change to make it work?


I'm no D expert, but here's what I got.

1. One problem is returning the wrong type from doIndex.  When 
the condition if(index.length == 1) is false, the subsequent 
line is still compiled but fails to return a ref T since 
array[index[0]] is an array of T, not a T.


The correct way (and better for performance, too) would be a 
compile-time static if there, like in the code below.  (I 
don't quite get the syntax of the template constraint for 
doIndex, so I've just commented that out for now.)


2. The next problem is that fixed-size arrays obey value 
semantics, so they should be passed by reference and not by 
value.


Here's what works for me (DMD 2.062):

-
import std.stdio;

template NDimensionalArrayType(T,alias size)
if(is(typeof(size) _ : const int[])  size.length  0)
{
static if(size.length  1)
alias NDimensionalArrayType!(T,size[1..$])[size[0]]
NDimensionalArrayType;
else
alias T[size[0]] NDimensionalArrayType;
}

struct NDimensionalArray(T,alias size)
{
private NDimensionalArrayType!(T,size) m_array;
	static ref T doIndex(Array)(ref Array array,const int[] index) 
//HERE

//  if(is(Array _ : NDimensionalArrayType!(T,s),const int[] s))
{
//  assert(index.length == s.length);
assert(index.length = size.length);
debug {writefln(doIndex (%s, %s = %s),
typeof(array).stringof,
typeof(index).stringof,
index);}
static if(is(Array : T[]))
{
assert(index.length == 1);
return array[index[0]];
}
else
{
assert(index.length  1);
return doIndex(array[index[0]],index[1..$]);
}
}
ref T opIndex(const int[] index)
{
return doIndex(m_array,index);
}
alias m_array this;
}

void main()
{
NDimensionalArray!(int,[5,2]) array;
array[[4,1]] = 1;
assert(array[[4,1]] == 1);
}
-

With the debug mode on, it successfully prints the following:

-
doIndex (int[2u][5u], const(int[]) = [4, 1])
doIndex (int[2u], const(int[]) = [1])
doIndex (int[2u][5u], const(int[]) = [4, 1])
doIndex (int[2u], const(int[]) = [1])
-

On a side note, this still looks like too much effort to do one 
opIndex in terms of performance.  I doubt that any current 
compiler would optimize all that into a simple multiply + 
bounds-check + add loop.


-
Ivan Kazmenko.


Thank you very much for your time)
Your answer is very useful.


  1   2   >