// type independent immutable string expr1 = OptionalChain!(string).autoReturn!("value.front"); immutable string expr2 = OptionalChain!(typeof(null)).autoReturn!("value.front"); import std.string : splitLines, strip, startsWith; import std.algorithm.iteration : map, filter, joiner; auto minify = (string t) => t.splitLines .map!(strip) .filter!(l => !l.empty) .filter!(l => !l.startsWith("//")) .joiner; auto minifiedExpr = minify(q{ auto ref expr() { return value.front; } auto ref val() { static if (isOptional!(typeof(expr()))) { return expr().front; } else { return expr(); } } alias R = typeof(val()); static if (is(R == void)) { if (!value.empty) { val(); } } else { if (value.empty) { return OptionalChain!R(none!R()); } static if (isOptional!(typeof(expr()))) { if (expr().empty) { return OptionalChain!R(none!R()); } } return OptionalChain!R(some(val())); } }); // just to make sure you dont make mistakes on minify assertFalse(minifiedExpr.array.empty); assertFalse(minify(expr1).array.empty); assertFalse(minify(expr2).array.empty); assertEquals(minifiedExpr.array, minify(expr1).array); assertEquals(minifiedExpr.array, minify(expr2).array);