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