How to get rid of const / immutable poisoning (and I didn't even want to use them...)
Enjoys Math via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon May 22 13:13:59 PDT 2017
On Monday, 22 May 2017 at 20:12:56 UTC, Enjoys Math wrote:
> I had to employ const / immutable to some things to get passed
> some compiler errors. Then the poisoning continues.
>
> How do I get this code to run?
>
> String's will hold a T[] which actually will not be modified by
> the String methods ("immutable strings of T").
>
> I did not want to use any immutable / const anywhere at first,
> but by passing in [1,2,3]
Crap. I hit tab then enter.
By passing in a constant array which is totally legit for testing
reasons, the compiler shits.
Here's the code:
------------
module smallest_grammar;
import std.conv;
import std.algorithm;
struct Symbol(T) {
public:
this(T sym, bool isVar) {
this.sym = sym;
this.is_var = isVar;
}
@property T symbol() { return sym; }
@property bool isVar() { return is_var; }
private:
T sym;
bool is_var = false;
}
immutable struct String(T) {
public:
this(immutable T[] s) {
this.s = s;
}
alias s this;
string toString() const { return to!string(s); }
string flattened() const { string t = ""; foreach (c; s) t ~=
to!string(c); return t; }
size_t toHash() const @system pure nothrow
{
return hashOf(flattened());
}
bool opEquals(ref const String t) const @system pure nothrow
{
if (t.length != this.length)
return false;
for(size_t k=0; k < t.length; k++)
if (t.s[k] != this.s[k]) return false;
return true;
}
// A compressible is a substring that occurs (non-overlappingly)
>=2 and has a length >= 3
// or one that occurs >= 3 and has a length of 2
String[] compressibles() const {
auto count = compressibleCount();
String[] substrings;
foreach (s, n; count)
substrings ~= s;
return substrings;
}
size_t[String] compressibleCount() const {
auto count = substringCount(2, size_t(s.length / 2));
foreach (str, n; count)
if (str.length == 2 && n < 3 || str.length >= 3 && n < 2)
count.remove(str);
return count;
}
String[] substrings(int minLen=0, int maxLen=-1) const {
auto count = substringCount();
String[] substrings;
foreach (s, n; count)
substrings ~= s;
return substrings;
}
size_t[String] substringCount(int minLen=0, int maxLen=-1) const
{
if (maxLen == -1)
maxLen = s.length;
assert (maxLen <= s.length && minLen >=0 && minLen <= maxLen);
size_t[String] count;
if (minLen == 0)
count[empty] = s.length + 1;
for (size_t i=0; i < s.length - minLen; i++) {
size_t max_len = min(s.length - i, maxLen);
for (size_t l=1; l < max_len; l++) {
auto substr = String(this.s[i..i+l]);
if (!(substr in count))
count[substr] = 0;
else
count[substr] ++;
}
}
return count;
}
public:
immutable(T)[] empty = [];
private
T[] s;
}
struct Grammar(T) {
public:
this(string name) { this.name = name; }
private:
string name;
String!(T)[][T] rules;
}
unittest {
import std.stdio;
// String
auto s = String!string(["1", "2", "34"]);
writeln(s);
writeln(s.flattened());
// Compressibles
s = String!string(["a", "b", "a", "b", "a", "b", "a"]);
writeln(s.substrings());
// Grammar
auto g = Grammar!string();
writeln("~ End Smallest Grammar unittests ~");
}
More information about the Digitalmars-d-learn
mailing list