Can Metaprogramming Help Here?

Mike Brown mikey.be at gmail.com
Wed Feb 24 20:10:30 UTC 2021


On Tuesday, 23 February 2021 at 22:55:53 UTC, H. S. Teoh wrote:
> On Tue, Feb 23, 2021 at 10:24:50PM +0000, Mike Brown via 
> Digitalmars-d-learn wrote:
>> Hi all,
>> 
>> Im porting some C++ code, which has a mess of a section that 
>> implements prime number type id's. I've had to smother it to 
>> death with test cases to get it reliable, I think 
>> metaprogramming that D provides is the better solution - Id 
>> rather not reimplement that C++ mess ideally.
>
> Try something like this:
>
> -----------------------------snip-----------------------------
> import std;
>
> int[] firstNPrimes(int n) {
> 	// FIXME: replace this with actual primes computation
> 	return [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 ];
> }
>
> string genEnum(string enumName, idents...)() {
> 	string code = "enum " ~ enumName ~ " {";
> 	auto primes = firstNPrimes(idents.length);
> 	foreach (i, ident; idents) {
> 		code ~= ident ~ " = " ~ primes[i].to!string ~ ", ";
> 	}
> 	code ~= "}";
> 	return code;
> }
>
> template PrimeEnum(idents...) {
> 	mixin(genEnum!("PrimeEnum", idents));
> }
>
> alias MyEnum = PrimeEnum!(
> 	"unknown", "newline", "identifier", "var", "user_defined",
> );
>
> void main() {
> 	writefln("%(%d\n%)", [
> 		MyEnum.unknown,
> 		MyEnum.newline,
> 		MyEnum.identifier,
> 		MyEnum.var,
> 		MyEnum.user_defined
> 	]);
> }
> -----------------------------snip-----------------------------
>
>
> You can substitute the body of firstNPrimes with any standard 
> prime-generation algorithm. As long as it's not too 
> heavyweight, you should be able to get it to compile without 
> the compiler soaking up unreasonable amounts of memory. :-D  If 
> you find the compiler using up too much memory, try 
> precomputing the list of primes beforehand and pasting it into 
> firstNPrimes (so that the CTFE engine doesn't have to recompute 
> it every time you compile).
>
> Note that PrimeEnum can be used to generate any number of enums 
> you wish to have prime values.  Or if you replace the call to 
> firstNPrimes with something else, you can generate enums whose 
> identifiers map to any integer sequence of your choosing.
>
>
> T

Hi T,

Thank you for the reply. Im struggling extending this to get the 
nesting working.

I'm trying something like:

string entry(string i, string[] inherit = []) {
	return i;
}

alias token_type2 = PrimeEnum!(
	entry("unknown"),
	entry("newline"),
	entry("identifier"),
	entry("var", ["identifier"]),
	entry("userDefined", ["identifier"])
);

Its worth noting that multiple inherited bases are needed too.

But I can't get those functions contexts linking, can I pass a 
function pointer as lazy into the PrimeEnum!() template?

Would it be easier to just parse the text at once into a single 
templating function?

Kind regards,
Mike Brown


More information about the Digitalmars-d-learn mailing list