Decoding Pattern to a Tuple
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Fri Feb 19 14:16:10 PST 2016
On 02/19/2016 11:04 AM, Ali Çehreli wrote:
> can be templatized:
Not ready for prime time but now it's templatized:
import std.stdio;
import std.string;
import std.regex;
import std.typecons;
import std.conv;
import std.algorithm;
import std.range;
template regexClass(T) {
static if (is (T == int)) {
// Warning: Treats "012" as int (value 12), not octal (value 10).
enum regexClass = `[0-9]+`;
} else static if (is (T == char)) {
enum regexClass = `.`;
} else static if (is (T == double)) {
enum regexClass = `[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?`;
} else {
static assert(false, format("Unsupported type %s", arg));
}
}
string regexEscape(string s) {
// TODO: Expand the array and fix the logic.
enum specialRegexChars = [ '(', ')' ];
return s.map!(c => (specialRegexChars.canFind(c)
? format("[%s]", c)
: format("%s", c)))
.joiner
.text;
}
auto parseDecodeArgs(Args...)(string matchedElementName) {
string regexString;
string tupleString = "return tuple(";
size_t selectionId = 1;
foreach (arg; Args) {
static if (is (arg)) {
regexString ~= format("(%s)", regexClass!arg);
tupleString ~=
format("%s[%s].to!%s, ",
matchedElementName, selectionId, arg.stringof);
++selectionId;
} else static if (is (typeof(arg) == string)) {
regexString ~= regexEscape(arg);
} else {
static assert(false, format("Unsupported type %s",
typeof(arg)));
}
}
tupleString ~= ");";
return tuple(regexString, tupleString);
}
auto decode(Args...)(string s) {
enum parseResult = parseDecodeArgs!Args("e");
enum r = ctRegex!(parseResult[0]);
// pragma(msg, parseResult[0]);
// pragma(msg, parseResult[1]);
auto matched = s.match(r);
if (matched) {
foreach (e; matched) {
mixin (parseResult[1]);
}
}
return typeof(return)();
}
void main() {
auto t = decode!("(", int, ")", char, "(", double, ")")("(1)-(2.5)");
writeln(t);
// Create a decoder for repeated use
auto decoder = (string s) => decode!(int, "/", double)(s);
// Decode each with the same decoder
auto decoded = ["1/1.5", "2/2.5", "3/3.5"]
.map!decoder;
writeln(decoded);
}
Ali
More information about the Digitalmars-d-learn
mailing list