Template/mixin ideas?
Sebastiaan Koppe
mail at skoppe.eu
Wed Oct 3 11:51:01 UTC 2018
On Wednesday, 3 October 2018 at 11:01:53 UTC, Chris Katko wrote:
> I've got this simple task but I'm trying to perfect it as best
> I can to learn something in the process.
>
> I have Linux terminal ASCII codes for coloring terminal output.
>
> string red(string) { /* ... */ }
>
> "Hello world".red => "\033[31mHello World\033[0m"
>
> which translates to "[red]Hello World[reset to normal text]".
>
> I have to do some slight trickery so I can chain them. But it
> all works fine. __The function is the same__ no matter what
> kind of color, bold, etc attribute I want. The only difference
> is the tag/prefix string.
>
> So I have a table (or enum):
> enum colors{
> reset = "\033[0m",
> red = "\033[31m",
> bold = "\033[1m" //...
> }
>
> Absolute perfection would be some way to add a single line to
> that enum (or table) and magically get a new function. I add
> "blue" with its prefix code to the enum and immediately I can
> do:
>
> "hello world".blue
>
> Add yellow = "\033..." and I can do:
>
> "hello world".bold.yellow
>
> It's an interesting problem. Right now, I made a generic
> version that accepts the prefix code string directly called
> "color()" and red() translates to a call to color with the red
> string. blue() does the same. And so on. But it's still plenty
> of boiler plate. I do that so I don't have 80+ functions all a
> half-page long--which would be a nightmare to verify.
>
> It's surely nothing mission critical. But I wonder if I can
> distill this simple problem down further, I may be able to
> learn some tricks for later problems.
>
> Thanks.
A combination of static introspection with string mixins does the
trick:
---
enum colors {
reset = "\033[0m",
red = "\033[31m"
}
auto GenerateColorFuncs() {
string result;
static foreach(c; __traits(allMembers, colors))
result ~= "auto "~c~"(string str) { return colors."~c~" ~
str ~ colors.reset; }";
return result;
}
mixin(GenerateColorFuncs());
void main()
{
import std.stdio;
writeln("bla".red);
}
---
Although you might want to replace the string concatenation with
something more performant if used a lot.
More information about the Digitalmars-d-learn
mailing list