Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion std/regex/internal/backtracking.d
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ struct CtContext
int addr;
}

this(Char)(const Regex!Char re)
this(Char)(ref const Regex!Char re)
{
match = 1;
reserved = 1; //first match is skipped
Expand Down
12 changes: 6 additions & 6 deletions std/regex/internal/ir.d
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ struct Group(DataIndex)
interface MatcherFactory(Char)
{
@safe:
Matcher!Char create(const Regex!Char, in Char[] input) const;
Matcher!Char create(const ref Regex!Char, in Char[] input) const;
Matcher!Char dup(Matcher!Char m, in Char[] input) const;
size_t incRef(Matcher!Char m) const;
size_t decRef(Matcher!Char m) const;
Expand All @@ -448,9 +448,9 @@ abstract class GenericFactory(alias EngineType, Char) : MatcherFactory!Char
// round up to next multiple of size_t for alignment purposes
enum classSize = (__traits(classInstanceSize, EngineType!Char) + size_t.sizeof - 1) & ~(size_t.sizeof - 1);

Matcher!Char construct(const Regex!Char re, in Char[] input, void[] memory) const;
Matcher!Char construct(const ref Regex!Char re, in Char[] input, void[] memory) const;

override Matcher!Char create(const Regex!Char re, in Char[] input) const @trusted
override Matcher!Char create(const ref Regex!Char re, in Char[] input) const @trusted
{
immutable size = EngineType!Char.initialMemory(re) + classSize;
auto memory = enforce(malloc(size), "malloc failed")[0 .. size];
Expand Down Expand Up @@ -496,7 +496,7 @@ abstract class GenericFactory(alias EngineType, Char) : MatcherFactory!Char
// A factory for run-time engines
class RuntimeFactory(alias EngineType, Char) : GenericFactory!(EngineType, Char)
{
override EngineType!Char construct(const Regex!Char re, in Char[] input, void[] memory) const
override EngineType!Char construct(const ref Regex!Char re, in Char[] input, void[] memory) const
{
import std.conv : emplace;
return emplace!(EngineType!Char)(memory[0 .. classSize],
Expand All @@ -507,7 +507,7 @@ class RuntimeFactory(alias EngineType, Char) : GenericFactory!(EngineType, Char)
// A factory for compile-time engine
class CtfeFactory(alias EngineType, Char, alias func) : GenericFactory!(EngineType, Char)
{
override EngineType!Char construct(const Regex!Char re, in Char[] input, void[] memory) const
override EngineType!Char construct(const ref Regex!Char re, in Char[] input, void[] memory) const
{
import std.conv : emplace;
return emplace!(EngineType!Char)(memory[0 .. classSize],
Expand All @@ -518,7 +518,7 @@ class CtfeFactory(alias EngineType, Char, alias func) : GenericFactory!(EngineTy
// A workaround for R-T enum re = regex(...)
template defaultFactory(Char)
{
@property MatcherFactory!Char defaultFactory(const Regex!Char re)
@property MatcherFactory!Char defaultFactory(const ref Regex!Char re) @safe
{
import std.regex.internal.backtracking : BacktrackingMatcher;
import std.regex.internal.thompson : ThompsonMatcher;
Expand Down
2 changes: 1 addition & 1 deletion std/regex/internal/thompson.d
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ final:
}
}

this()(const Regex!Char program, Stream stream, void[] memory)
this()(ref const Regex!Char program, Stream stream, void[] memory)
{
// We are emplace'd to malloced memory w/o blitting T.init over it\
// make sure we initialize all fields explicitly
Expand Down
33 changes: 27 additions & 6 deletions std/regex/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -441,12 +441,22 @@ template ctRegexImpl(alias pattern, string flags=[])
{
// allow code that expects mutable Regex to still work
// we stay "logically const"
@trusted @property auto getRe() const { return cast() staticRe; }
@property @trusted ref getRe() const { return *cast(Regex!Char*)&staticRe; }
alias getRe this;
}
enum wrapper = Wrapper();
}

@safe unittest
{
// test compat for logical const workaround
static void test(StaticRegex!char)
{
}
enum re = ctRegex!``;
test(re);
}

/++
Compile regular expression using CTFE
and generate optimized native machine code for matching it.
Expand Down Expand Up @@ -476,18 +486,18 @@ if (isSomeString!R)
alias String = R;
private:
import std.conv : text;
R _input;
int _nMatch;
enum smallString = 3;
enum SMALL_MASK = 0x8000_0000, REF_MASK= 0x1FFF_FFFF;
union
{
Group!DataIndex[] big_matches;
Group!DataIndex[smallString] small_matches;
}
const(NamedGroup)[] _names;
R _input;
int _nMatch;
uint _f, _b;
uint _refcount; // ref count or SMALL MASK + num groups
const(NamedGroup)[] _names;

this(R input, uint n, const(NamedGroup)[] named)
{
Expand Down Expand Up @@ -671,6 +681,17 @@ public:

///A hook for compatibility with original std.regex.
@property ref captures(){ return this; }

void opAssign()(auto ref Captures rhs)
{
if (rhs._refcount & SMALL_MASK)
small_matches[0 .. rhs._refcount & 0xFF] = rhs.small_matches[0 .. rhs._refcount & 0xFF];
else
big_matches = rhs.big_matches;
assert(&this.tupleof[0] is &big_matches);
assert(&this.tupleof[1] is &small_matches);
this.tupleof[2 .. $] = rhs.tupleof[2 .. $];
}
}

///
Expand Down Expand Up @@ -802,7 +823,7 @@ public:
@property inout(Captures!R) captures() inout { return _captures; }
}

private @trusted auto matchOnce(RegEx, R)(R input, const RegEx prog)
private @trusted auto matchOnce(RegEx, R)(R input, const auto ref RegEx prog)
{
alias Char = BasicElementOf!R;
auto factory = prog.factory is null ? defaultFactory!Char(prog) : prog.factory;
Expand All @@ -813,7 +834,7 @@ private @trusted auto matchOnce(RegEx, R)(R input, const RegEx prog)
return captures;
}

private auto matchMany(RegEx, R)(R input, RegEx re) @safe
private auto matchMany(RegEx, R)(R input, auto ref RegEx re) @safe
{
return RegexMatch!R(input, re.withFlags(re.flags | RegexOption.global));
}
Expand Down