mirror of
https://github.com/dlang/phobos.git
synced 2025-04-27 21:51:40 +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=[])
|
||||
{
|
||||
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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue