mirror of
https://github.com/dlang/phobos.git
synced 2025-04-30 15:10:46 +03:00
std.regex: Fix reassignment of ctRegex wrapper structs
Previously, reassigning such a wrapper resulted in the static immutable Regex!Char global for that pattern (`staticRe`) to be overwritten by the global for the new pattern (!). Made possible via alias this and the logical-const hack. Proposed fix: keep on allowing reassignments (people are already using them), but just point to another pattern's global. So use a common Wrapper struct type wrapping a pointer instead of an empty struct type per pattern. Bug reported in https://github.com/ldc-developers/ldc/issues/2961.
This commit is contained in:
parent
6a759b85f2
commit
5cc7fc5fb2
1 changed files with 22 additions and 8 deletions
|
@ -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=[])
|
template ctRegexImpl(alias pattern, string flags=[])
|
||||||
{
|
{
|
||||||
import std.regex.internal.backtracking, std.regex.internal.parser;
|
import std.regex.internal.backtracking, std.regex.internal.parser;
|
||||||
|
@ -437,14 +447,7 @@ template ctRegexImpl(alias pattern, string flags=[])
|
||||||
}
|
}
|
||||||
static immutable staticRe =
|
static immutable staticRe =
|
||||||
cast(immutable) r.withFactory(new CtfeFactory!(BacktrackingMatcher, Char, func));
|
cast(immutable) r.withFactory(new CtfeFactory!(BacktrackingMatcher, Char, func));
|
||||||
struct Wrapper
|
enum wrapper = CTRegexWrapper!Char(&staticRe);
|
||||||
{
|
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@safe unittest
|
@safe unittest
|
||||||
|
@ -457,6 +460,17 @@ template ctRegexImpl(alias pattern, string flags=[])
|
||||||
test(re);
|
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
|
Compile regular expression using CTFE
|
||||||
and generate optimized native machine code for matching it.
|
and generate optimized native machine code for matching it.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue