diff --git a/std/regex/package.d b/std/regex/package.d index 2f8ea0cbf..15dee8c18 100644 --- a/std/regex/package.d +++ b/std/regex/package.d @@ -423,6 +423,16 @@ if (isSomeString!(S)) } +private struct CTRegexWrapper(Char) +{ + private immutable(Regex!Char)* re; + + // allow code that expects mutable Regex to still work + // we stay "logically const" + @property @trusted ref getRe() const { return *cast(Regex!Char*) re; } + alias getRe this; +} + template ctRegexImpl(alias pattern, string flags=[]) { import std.regex.internal.backtracking, std.regex.internal.parser; @@ -437,14 +447,7 @@ template ctRegexImpl(alias pattern, string flags=[]) } static immutable staticRe = cast(immutable) r.withFactory(new CtfeFactory!(BacktrackingMatcher, Char, func)); - struct Wrapper - { - // allow code that expects mutable Regex to still work - // we stay "logically const" - @property @trusted ref getRe() const { return *cast(Regex!Char*)&staticRe; } - alias getRe this; - } - enum wrapper = Wrapper(); + enum wrapper = CTRegexWrapper!Char(&staticRe); } @safe unittest @@ -457,6 +460,17 @@ template ctRegexImpl(alias pattern, string flags=[]) test(re); } +@safe unittest +{ + auto re = ctRegex!`foo`; + assert(matchFirst("foo", re)); + + // test reassignment + re = ctRegex!`bar`; + assert(matchFirst("bar", re)); + assert(!matchFirst("bar", ctRegex!`foo`)); +} + /++ Compile regular expression using CTFE and generate optimized native machine code for matching it.