summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2017-05-12 20:55:42 +0200
committerEugen Wissner <belka@caraus.de>2017-05-12 20:55:42 +0200
commit38afeac0719d536e941201f8754a193db703169f (patch)
treec922aca556691c3daadfbf51dea808ac6ecc38a7 /source
parent001c7c3e3399eab1dd89b0d4e52b435e3e4fff8a (diff)
downloadtanya-38afeac0719d536e941201f8754a193db703169f.tar.gz
Insert String.insertFront and String.insertBack
Diffstat (limited to 'source')
-rw-r--r--source/tanya/container/string.d85
-rw-r--r--source/tanya/container/vector.d38
2 files changed, 99 insertions, 24 deletions
diff --git a/source/tanya/container/string.d b/source/tanya/container/string.d
index 5cf44c1..5ae4cbc 100644
--- a/source/tanya/container/string.d
+++ b/source/tanya/container/string.d
@@ -1361,6 +1361,7 @@ struct String
* Remove all characters beloning to $(D_PARAM r).
*
* Params:
+ * R = $(D_PSYMBOL ByCodeUnit) or $(D_PSYMBOL ByCodePoint).
* r = Range originally obtained from this string.
*
* Returns: A range spanning the remaining characters in the string that
@@ -1368,7 +1369,7 @@ struct String
*
* Precondition: $(D_PARAM r) refers to a region of $(D_KEYWORD this).
*/
- R remove(R)(R r) pure nothrow @trusted @nogc
+ R remove(R)(R r) @trusted
if (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char))
in
{
@@ -1387,11 +1388,11 @@ struct String
///
@nogc @safe unittest
{
- auto s = String("Из пословицы слова не выкинешь");
+ auto s = String("Из пословицы слова не выкинешь.");
- assert(s.remove(s[5 .. 24]).length == 32);
- assert(s == "Из слова не выкинешь");
- assert(s.length == 37);
+ assert(s.remove(s[5 .. 24]).length == 33);
+ assert(s == "Из слова не выкинешь.");
+ assert(s.length == 38);
auto byCodePoint = s.byCodePoint();
byCodePoint.popFrontN(8);
@@ -1405,5 +1406,79 @@ struct String
assert(s.remove(s[]).length == 0);
}
+ /**
+ * Inserts $(D_PARAM el) before or after $(D_PARAM r).
+ *
+ * Params:
+ * R = $(D_PSYMBOL ByCodeUnit) or $(D_PSYMBOL ByCodePoint).
+ * T = Stringish type.
+ * r = Range originally obtained from this vector.
+ * el = Value(s) should be inserted.
+ *
+ * Returns: The number of elements inserted.
+ *
+ * Precondition: $(D_PARAM r) refers to a region of $(D_KEYWORD this).
+ */
+ size_t insertAfter(T, R)(R r, T el) @trusted
+ if ((isSomeChar!T || (!isInfinite!T
+ && isInputRange!T
+ && isSomeChar!(ElementEncodingType!T)))
+ && (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char)))
+ in
+ {
+ assert(r.container is &this);
+ assert(r.begin >= this.data);
+ assert(r.end <= this.data + length);
+ }
+ body
+ {
+ const oldLen = length;
+ const offset = r.end - this.data;
+ const inserted = insertBack(el);
+ bringToFront(this.data[offset .. oldLen], this.data[oldLen .. length]);
+ return inserted;
+ }
+
+ ///
+ @nogc @safe unittest
+ {
+ auto s = String("Нельзя казнить помиловать.");
+ s.insertAfter(s[0 .. 27], ",");
+ assert(s == "Нельзя казнить, помиловать.");
+
+ s = String("Нельзя казнить помиловать.");
+ s.insertAfter(s[0 .. 27], ',');
+ assert(s == "Нельзя казнить, помиловать.");
+ }
+
+ ///
+ size_t insertBefore(T, R)(R r, T el) @trusted
+ if ((isSomeChar!T || (!isInfinite!T
+ && isInputRange!T
+ && isSomeChar!(ElementEncodingType!T)))
+ && (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char)))
+ in
+ {
+ assert(r.container is &this);
+ assert(r.begin >= this.data);
+ assert(r.end <= this.data + length);
+ }
+ body
+ {
+ return insertAfter(R(this, this.data, r.begin), el);
+ }
+
+ ///
+ @nogc @safe unittest
+ {
+ auto s = String("Нельзя казнить помиловать.");
+ s.insertBefore(s[27 .. $], ",");
+ assert(s == "Нельзя казнить, помиловать.");
+
+ s = String("Нельзя казнить помиловать.");
+ s.insertBefore(s[27 .. $], ',');
+ assert(s == "Нельзя казнить, помиловать.");
+ }
+
mixin DefaultAllocator;
}
diff --git a/source/tanya/container/vector.d b/source/tanya/container/vector.d
index 969720e..7f5e3a5 100644
--- a/source/tanya/container/vector.d
+++ b/source/tanya/container/vector.d
@@ -32,26 +32,26 @@ struct Range(E)
{
private E* begin, end;
private alias ContainerType = CopyConstness!(E, Vector!(Unqual!E));
- private ContainerType* vector;
+ private ContainerType* container;
invariant
{
assert(this.begin <= this.end);
- assert(this.vector !is null);
- assert(this.begin >= this.vector.data);
- assert(this.end <= this.vector.data + this.vector.length);
+ assert(this.container !is null);
+ assert(this.begin >= this.container.data);
+ assert(this.end <= this.container.data + this.container.length);
}
- private this(ref ContainerType vector, E* begin, E* end) @trusted
+ private this(ref ContainerType container, E* begin, E* end) @trusted
in
{
assert(begin <= end);
- assert(begin >= vector.data);
- assert(end <= vector.data + vector.length);
+ assert(begin >= container.data);
+ assert(end <= container.data + container.length);
}
body
{
- this.vector = &vector;
+ this.container = &container;
this.begin = begin;
this.end = end;
}
@@ -127,12 +127,12 @@ struct Range(E)
Range opIndex()
{
- return typeof(return)(*this.vector, this.begin, this.end);
+ return typeof(return)(*this.container, this.begin, this.end);
}
Range!(const E) opIndex() const
{
- return typeof(return)(*this.vector, this.begin, this.end);
+ return typeof(return)(*this.container, this.begin, this.end);
}
Range opSlice(const size_t i, const size_t j) @trusted
@@ -143,7 +143,7 @@ struct Range(E)
}
body
{
- return typeof(return)(*this.vector, this.begin + i, this.begin + j);
+ return typeof(return)(*this.container, this.begin + i, this.begin + j);
}
Range!(const E) opSlice(const size_t i, const size_t j) const @trusted
@@ -154,7 +154,7 @@ struct Range(E)
}
body
{
- return typeof(return)(*this.vector, this.begin + i, this.begin + j);
+ return typeof(return)(*this.container, this.begin + i, this.begin + j);
}
inout(E[]) get() inout @trusted
@@ -638,7 +638,7 @@ struct Vector(T)
Range!T remove(Range!T r) @trusted
in
{
- assert(r.vector is &this);
+ assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
@@ -791,7 +791,7 @@ struct Vector(T)
&& isImplicitlyConvertible!(ElementType!R, T))
in
{
- assert(r.vector is &this);
+ assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
@@ -808,7 +808,7 @@ struct Vector(T)
size_t insertAfter(size_t R)(Range!T r, T[R] el)
in
{
- assert(r.vector is &this);
+ assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
@@ -822,7 +822,7 @@ struct Vector(T)
if (isImplicitlyConvertible!(R, T))
in
{
- assert(r.vector is &this);
+ assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
@@ -851,7 +851,7 @@ struct Vector(T)
&& isImplicitlyConvertible!(ElementType!R, T))
in
{
- assert(r.vector is &this);
+ assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
@@ -864,7 +864,7 @@ struct Vector(T)
size_t insertBefore(size_t R)(Range!T r, T[R] el)
in
{
- assert(r.vector is &this);
+ assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}
@@ -878,7 +878,7 @@ struct Vector(T)
if (isImplicitlyConvertible!(R, T))
in
{
- assert(r.vector is &this);
+ assert(r.container is &this);
assert(r.begin >= this.data);
assert(r.end <= this.data + length);
}