www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to list all the manifest constants in a class or struct

reply Heromyth <bitworld qq.com> writes:
Here is a struct named S:

struct S
{
	enum X = 10;
	enum Y
	{
	  i = 10
	}
	enum Z = "str";
	struct S {}
	class C {}

	static int sx = 0;
	__gshared int gx = 0;

         shared void g();	
}

I want list all then the manifest constants in it.

I searched the std.traits and this forums, but get nothing.
Maybe, my real question is how to get the storage class for a 
member in a class or struct.

Thanks.
Jun 16 2018
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, June 17, 2018 02:44:38 Heromyth via Digitalmars-d-learn wrote:
 Here is a struct named S:

 struct S
 {
   enum X = 10;
   enum Y
   {
     i = 10
   }
   enum Z = "str";
   struct S {}
   class C {}

   static int sx = 0;
   __gshared int gx = 0;

          shared void g();
 }

 I want list all then the manifest constants in it.

 I searched the std.traits and this forums, but get nothing.
 Maybe, my real question is how to get the storage class for a
 member in a class or struct.
As the storage class isn't part of the type, type introspection tends to ignore it. You'll basically have to get the full list of members of the type and then filter out stuff that isn't a manifest constant, which is not exactly pleasant and can get a bit tricky but should be possible. You'll probably have to do something like filter out all of the members where you can take their address and filter out all of the ones that are types, and and at that point, you'd be close, but I'd have to experiment to figure out whether that was enough or not or whether something crept through. Andrei has been working on coming up with a better wrapper around the current introspection stuff so that you'll actually get data types which contain the information about a symbol rather than having to figure out which combination of __traits and traits from std.traits are required to get what you want. So, I expect that stuff like this will get a lot easier once that's ready, but in the interim, if you're trying to do something less common, it can involve having to do a lot clever filtering to get exactly the stuff you want and only the stuff you want - and I don't think that getting the list of manifest constants in a type is a very typical thing for folks to do, so std.traits certainly doesn't have anything like isManifestConstant. - Jonathan M Davis
Jun 16 2018
parent Heromyth <bitworld qq.com> writes:
On Sunday, 17 June 2018 at 04:32:29 UTC, Jonathan M Davis wrote:
 On Sunday, June 17, 2018 02:44:38 Heromyth via 
 Digitalmars-d-learn wrote:
 Here is a struct named S:

 struct S
 {
   enum X = 10;
   enum Y
   {
     i = 10
   }
   enum Z = "str";
   struct S {}
   class C {}

   static int sx = 0;
   __gshared int gx = 0;

          shared void g();
 }

 I want list all then the manifest constants in it.

 I searched the std.traits and this forums, but get nothing. 
 Maybe, my real question is how to get the storage class for a 
 member in a class or struct.
As the storage class isn't part of the type, type introspection tends to ignore it. You'll basically have to get the full list of members of the type and then filter out stuff that isn't a manifest constant, which is not exactly pleasant and can get a bit tricky but should be possible. You'll probably have to do something like filter out all of the members where you can take their address and filter out all of the ones that are types, and and at that point, you'd be close, but I'd have to experiment to figure out whether that was enough or not or whether something crept through. Andrei has been working on coming up with a better wrapper around the current introspection stuff so that you'll actually get data types which contain the information about a symbol rather than having to figure out which combination of __traits and traits from std.traits are required to get what you want. So, I expect that stuff like this will get a lot easier once that's ready, but in the interim, if you're trying to do something less common, it can involve having to do a lot clever filtering to get exactly the stuff you want and only the stuff you want - and I don't think that getting the list of manifest constants in a type is a very typical thing for folks to do, so std.traits certainly doesn't have anything like isManifestConstant. - Jonathan M Davis
Thanks for your answers. It's so glad to see some works have been taken for this. The isManifestConstant is really necessary. For example, I want to port an Enum type from Java to D. It seems better to use a Struct instead of an Enum. See here: https://github.com/eclipse/jetty.project/blob/jetty-9.4.x/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java https://github.com/eclipse/jetty.project/blob/jetty-9.4.x/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeaderValue.java Of course, I can define a enum for members with the basic types in D. Sometimes, I like to define them in a class or struct as manifest constants or immutable ones. So, I need isManifestConstant.
Jun 17 2018
prev sibling parent reply aliak <something something.com> writes:
On Sunday, 17 June 2018 at 02:44:38 UTC, Heromyth wrote:
 Here is a struct named S:

 struct S
 {
 	enum X = 10;
 	enum Y
 	{
 	  i = 10
 	}
 	enum Z = "str";
 	struct S {}
 	class C {}

 	static int sx = 0;
 	__gshared int gx = 0;

         shared void g();	
 }

 I want list all then the manifest constants in it.

 I searched the std.traits and this forums, but get nothing.
 Maybe, my real question is how to get the storage class for a 
 member in a class or struct.

 Thanks.
I think this bolts.isManifestAssignable [1] will get you partially there. The place where it'll fail though is a static immutable (since they are assignable to manifest constants) but you can filter those by seeing if you can take the address, something like: foreach (m; __traits(allMembers, T)) { if (isManifestAssignable!(T, m) && !is(typeof(mixin("&T."~m))) { // it's a manifest constant ... (?) } } There of course might be edge cases I can't think of/don't know about though. Cheers, - Ali http://bolts.dpldocs.info/bolts.traits.isManifestAssignable.html
Jun 17 2018
parent Heromyth <bitworld qq.com> writes:
On Sunday, 17 June 2018 at 20:03:09 UTC, aliak wrote:
 On Sunday, 17 June 2018 at 02:44:38 UTC, Heromyth wrote:
 [...]
I think this bolts.isManifestAssignable [1] will get you partially there. The place where it'll fail though is a static immutable (since they are assignable to manifest constants) but you can filter those by seeing if you can take the address, something like: foreach (m; __traits(allMembers, T)) { if (isManifestAssignable!(T, m) && !is(typeof(mixin("&T."~m))) { // it's a manifest constant ... (?) } } There of course might be edge cases I can't think of/don't know about though. Cheers, - Ali http://bolts.dpldocs.info/bolts.traits.isManifestAssignable.html
Thant's it. Thanks for your great lib: https://github.com/aliak00/bolts
Jun 17 2018