www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Associating symbols with attributes (D 2.0)

reply Burton Radons <burton.radons gmail.com> writes:
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
parent %u <a bcd.com> writes:
 Anyone have a clue about any of these issues?

Use Lisp ;-)
Mar 06 2009