Insert String.insertFront and String.insertBack
This commit is contained in:
parent
001c7c3e33
commit
38afeac071
@ -1361,6 +1361,7 @@ struct String
|
|||||||
* Remove all characters beloning to $(D_PARAM r).
|
* Remove all characters beloning to $(D_PARAM r).
|
||||||
*
|
*
|
||||||
* Params:
|
* Params:
|
||||||
|
* R = $(D_PSYMBOL ByCodeUnit) or $(D_PSYMBOL ByCodePoint).
|
||||||
* r = Range originally obtained from this string.
|
* r = Range originally obtained from this string.
|
||||||
*
|
*
|
||||||
* Returns: A range spanning the remaining characters in the string that
|
* 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).
|
* 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))
|
if (is(R == ByCodeUnit!char) || is(R == ByCodePoint!char))
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@ -1387,11 +1388,11 @@ struct String
|
|||||||
///
|
///
|
||||||
@nogc @safe unittest
|
@nogc @safe unittest
|
||||||
{
|
{
|
||||||
auto s = String("Из пословицы слова не выкинешь");
|
auto s = String("Из пословицы слова не выкинешь.");
|
||||||
|
|
||||||
assert(s.remove(s[5 .. 24]).length == 32);
|
assert(s.remove(s[5 .. 24]).length == 33);
|
||||||
assert(s == "Из слова не выкинешь");
|
assert(s == "Из слова не выкинешь.");
|
||||||
assert(s.length == 37);
|
assert(s.length == 38);
|
||||||
|
|
||||||
auto byCodePoint = s.byCodePoint();
|
auto byCodePoint = s.byCodePoint();
|
||||||
byCodePoint.popFrontN(8);
|
byCodePoint.popFrontN(8);
|
||||||
@ -1405,5 +1406,79 @@ struct String
|
|||||||
assert(s.remove(s[]).length == 0);
|
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;
|
mixin DefaultAllocator;
|
||||||
}
|
}
|
||||||
|
@ -32,26 +32,26 @@ struct Range(E)
|
|||||||
{
|
{
|
||||||
private E* begin, end;
|
private E* begin, end;
|
||||||
private alias ContainerType = CopyConstness!(E, Vector!(Unqual!E));
|
private alias ContainerType = CopyConstness!(E, Vector!(Unqual!E));
|
||||||
private ContainerType* vector;
|
private ContainerType* container;
|
||||||
|
|
||||||
invariant
|
invariant
|
||||||
{
|
{
|
||||||
assert(this.begin <= this.end);
|
assert(this.begin <= this.end);
|
||||||
assert(this.vector !is null);
|
assert(this.container !is null);
|
||||||
assert(this.begin >= this.vector.data);
|
assert(this.begin >= this.container.data);
|
||||||
assert(this.end <= this.vector.data + this.vector.length);
|
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
|
in
|
||||||
{
|
{
|
||||||
assert(begin <= end);
|
assert(begin <= end);
|
||||||
assert(begin >= vector.data);
|
assert(begin >= container.data);
|
||||||
assert(end <= vector.data + vector.length);
|
assert(end <= container.data + container.length);
|
||||||
}
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
this.vector = &vector;
|
this.container = &container;
|
||||||
this.begin = begin;
|
this.begin = begin;
|
||||||
this.end = end;
|
this.end = end;
|
||||||
}
|
}
|
||||||
@ -127,12 +127,12 @@ struct Range(E)
|
|||||||
|
|
||||||
Range opIndex()
|
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
|
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
|
Range opSlice(const size_t i, const size_t j) @trusted
|
||||||
@ -143,7 +143,7 @@ struct Range(E)
|
|||||||
}
|
}
|
||||||
body
|
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
|
Range!(const E) opSlice(const size_t i, const size_t j) const @trusted
|
||||||
@ -154,7 +154,7 @@ struct Range(E)
|
|||||||
}
|
}
|
||||||
body
|
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
|
inout(E[]) get() inout @trusted
|
||||||
@ -638,7 +638,7 @@ struct Vector(T)
|
|||||||
Range!T remove(Range!T r) @trusted
|
Range!T remove(Range!T r) @trusted
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(r.vector is &this);
|
assert(r.container is &this);
|
||||||
assert(r.begin >= this.data);
|
assert(r.begin >= this.data);
|
||||||
assert(r.end <= this.data + length);
|
assert(r.end <= this.data + length);
|
||||||
}
|
}
|
||||||
@ -791,7 +791,7 @@ struct Vector(T)
|
|||||||
&& isImplicitlyConvertible!(ElementType!R, T))
|
&& isImplicitlyConvertible!(ElementType!R, T))
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(r.vector is &this);
|
assert(r.container is &this);
|
||||||
assert(r.begin >= this.data);
|
assert(r.begin >= this.data);
|
||||||
assert(r.end <= this.data + length);
|
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)
|
size_t insertAfter(size_t R)(Range!T r, T[R] el)
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(r.vector is &this);
|
assert(r.container is &this);
|
||||||
assert(r.begin >= this.data);
|
assert(r.begin >= this.data);
|
||||||
assert(r.end <= this.data + length);
|
assert(r.end <= this.data + length);
|
||||||
}
|
}
|
||||||
@ -822,7 +822,7 @@ struct Vector(T)
|
|||||||
if (isImplicitlyConvertible!(R, T))
|
if (isImplicitlyConvertible!(R, T))
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(r.vector is &this);
|
assert(r.container is &this);
|
||||||
assert(r.begin >= this.data);
|
assert(r.begin >= this.data);
|
||||||
assert(r.end <= this.data + length);
|
assert(r.end <= this.data + length);
|
||||||
}
|
}
|
||||||
@ -851,7 +851,7 @@ struct Vector(T)
|
|||||||
&& isImplicitlyConvertible!(ElementType!R, T))
|
&& isImplicitlyConvertible!(ElementType!R, T))
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(r.vector is &this);
|
assert(r.container is &this);
|
||||||
assert(r.begin >= this.data);
|
assert(r.begin >= this.data);
|
||||||
assert(r.end <= this.data + length);
|
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)
|
size_t insertBefore(size_t R)(Range!T r, T[R] el)
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(r.vector is &this);
|
assert(r.container is &this);
|
||||||
assert(r.begin >= this.data);
|
assert(r.begin >= this.data);
|
||||||
assert(r.end <= this.data + length);
|
assert(r.end <= this.data + length);
|
||||||
}
|
}
|
||||||
@ -878,7 +878,7 @@ struct Vector(T)
|
|||||||
if (isImplicitlyConvertible!(R, T))
|
if (isImplicitlyConvertible!(R, T))
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert(r.vector is &this);
|
assert(r.container is &this);
|
||||||
assert(r.begin >= this.data);
|
assert(r.begin >= this.data);
|
||||||
assert(r.end <= this.data + length);
|
assert(r.end <= this.data + length);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user