digitalmars.D - Associating symbols with attributes (D 2.0)
- Burton Radons (43/43) Mar 05 2009 I'm working on a string conversion template (well, incidentally to more ...
- Burton Radons (1/1) Mar 06 2009 Not even the great Jarrett Billingsley has done this one? Daaaamn. Guess...
- Jarrett Billingsley (6/7) Mar 06 2009 Psh! Most template hacking I learned from the best - Don and Kirk :P
- Burton Radons (15/25) Mar 06 2009 Works great actually. The only thing I needed to do was turn __traits (a...
- Jarrett Billingsley (5/8) Mar 06 2009 lMembers) from whatever the hell it is into an actual tuple:
- Don (6/40) Mar 09 2009 If you have it in the form of an alias parameter, you can pass it
- %u (1/2) Mar 06 2009 Use Lisp ;-)
I'm working on a string conversion template (well, incidentally to more important stuff). I've got it automatically converting enumerations to strings, but I have mask-type enumerations, single-value enumerations, and combination enumerations where there's a value in one part of the integer and a mask in the other. For this and a couple other reasons I need to be able to specify attributes for a symbol at the declaration point of the symbol. My initial idea is like: enum Foo { } mixin attributes! (Foo, "toString.enum", "mask"); (I probably wouldn't use string literals of course - the API that it's an attribute for could provide a template function for generating the proper attribute names). All attributes does is alias a tuple to a mangled symbol name. Then to query it I'd just use: static if (getAttribute! (U, "toString.enum", "value") == "mask") ... treat the enumeration as a mask ... else ... treat the enumeration as a value ... I don't like that it's associated with a name rather than the symbol itself; that'll either limit its applications or make some applications more convoluted than desirable. I also don't like having the mixin there. The former problem could be solved for some symbols by putting the attributes within the scope of the symbol, but that won't work for functions/methods which are the worst affected by this limitation. Perhaps more critically, it doesn't work. For example: template attributes (alias T, A...) { pragma (msg, "attributes: " ~ attributesName! (T)); mixin ("alias A " ~ attributesName! (T) ~ ";"); } template attributesName (alias T) { invariant attributesName = T.stringof ~ "_attributes"; } template getAttributes (alias T) { mixin ("alias " ~ attributesName! (T) ~ " getAttributes;"); } struct Container { struct Foo { } mixin attributes! (Foo, "hello", "world"); void test () { pragma (msg, "Hello world: " ~ getAttributes! (Foo).stringof); } } The problem is that stringof should but doesn't give a name that absolutely finds the symbol; it just gives "Foo", when what's needed in the getAttributes context is "Container.Foo" or, better yet, an internal compiler symbol that unambiguously determines the symbol (like the mangled name, but discoverable from any context). Putting the attributes in the global scope solves the problem, but it's nicer if they're attached to the symbol, and it doesn't help when the module isn't imported into the getAttributes scope which will be exactly 100% of the time. Anyone have a clue about any of these issues?
Mar 05 2009
Not even the great Jarrett Billingsley has done this one? Daaaamn. Guess we will need attributes then.
Mar 06 2009
On Fri, Mar 6, 2009 at 4:25 PM, Burton Radons <burton.radons shaw.ca> wrote:Not even the great Jarrett Billingsley has done this one? Daaaamn. Guess we will need attributes then.Psh! Most template hacking I learned from the best - Don and Kirk :P Don't bother introspecting enums. It will give you nothing but sadness. The compiler hates enums in many ways. Perhaps .mangleof will work? You'll have to parse it out if you want a prettier name, but..
Mar 06 2009
Jarrett Billingsley Wrote:On Fri, Mar 6, 2009 at 4:25 PM, Burton Radons <burton.radons shaw.ca> wrote:Works great actually. The only thing I needed to do was turn __traits (allMembers) from whatever the hell it is into an actual tuple: template memberNames (T) { mixin ("alias tuple! (" ~ (__traits (allMembers, T).stringof [1 .. $ - 1]) ~ ") memberNames;"); } This gives me the correct list of names, and those all work just fine with mixins. I was going to go with an enumeration builder function but I just can't lose autodoc.Not even the great Jarrett Billingsley has done this one? Daaaamn. Guess we will need attributes then.Psh! Most template hacking I learned from the best - Don and Kirk :P Don't bother introspecting enums. It will give you nothing but sadness. The compiler hates enums in many ways.Perhaps .mangleof will work? You'll have to parse it out if you want a prettier name, but..No, it's a scope issue. The symbol itself is visible in that scope because it's an argument to the template, but from that point in the scope you can only reach symbols that are deeper, not further out. The only hope I could see would be for mixin expressions: template getAttributes (T, U = mixin (T.stringof ~ "_attributes")) { alias U getAttributes; } However, I have no idea how I could possibly make that work with symbols which don't have any attributes defined for them. I just ended up putting a false value in the enumeration with special meaning, which sucks.
Mar 06 2009
On Fri, Mar 6, 2009 at 7:26 PM, Burton Radons <burton.radons shaw.ca> wrote= :lMembers) from whatever the hell it is into an actual tuple: Oh - D2. Well that precludes my participation in this conversation entirel= y.Don't bother introspecting enums. =A0It will give you nothing but sadness. =A0The compiler hates enums in many ways.Works great actually. The only thing I needed to do was turn __traits (al=
Mar 06 2009
Burton Radons wrote:Jarrett Billingsley Wrote:If you have it in the form of an alias parameter, you can pass it deeper. The fundamental problem to solve is to turn the __traits(allMembers) into an alias tuple. I don't know if that's possible right now -- your chance of encountering compiler bugs is very high.On Fri, Mar 6, 2009 at 4:25 PM, Burton Radons <burton.radons shaw.ca> wrote:Works great actually. The only thing I needed to do was turn __traits (allMembers) from whatever the hell it is into an actual tuple: template memberNames (T) { mixin ("alias tuple! (" ~ (__traits (allMembers, T).stringof [1 .. $ - 1]) ~ ") memberNames;"); } This gives me the correct list of names, and those all work just fine with mixins. I was going to go with an enumeration builder function but I just can't lose autodoc.Not even the great Jarrett Billingsley has done this one? Daaaamn. Guess we will need attributes then.Psh! Most template hacking I learned from the best - Don and Kirk :P Don't bother introspecting enums. It will give you nothing but sadness. The compiler hates enums in many ways.Perhaps .mangleof will work? You'll have to parse it out if you want a prettier name, but..No, it's a scope issue. The symbol itself is visible in that scope because it's an argument to the template, but from that point in the scope you can only reach symbols that are deeper, not further out.The only hope I could see would be for mixin expressions: template getAttributes (T, U = mixin (T.stringof ~ "_attributes")) { alias U getAttributes; } However, I have no idea how I could possibly make that work with symbols which don't have any attributes defined for them. I just ended up putting a false value in the enumeration with special meaning, which sucks.
Mar 09 2009