diff --git a/source/tanya/algorithm/mutation.d b/source/tanya/algorithm/mutation.d index df741cc..bf39b22 100644 --- a/source/tanya/algorithm/mutation.d +++ b/source/tanya/algorithm/mutation.d @@ -14,8 +14,9 @@ */ module tanya.algorithm.mutation; -import tanya.memory.op; +static import tanya.memory.op; import tanya.meta.trait; +import tanya.range; private void deinitialize(bool zero, T)(ref T value) { @@ -39,11 +40,12 @@ private void deinitialize(bool zero, T)(ref T value) } static if (zero) { - fill!0((cast(void*) &value)[0 .. size]); + tanya.memory.op.fill!0((cast(void*) &value)[0 .. size]); } else { - copy(typeid(T).initializer()[0 .. size], (&value)[0 .. 1]); + tanya.memory.op.copy(typeid(T).initializer()[0 .. size], + (&value)[0 .. 1]); } } } @@ -81,7 +83,7 @@ do { static if (is(T == struct) || isStaticArray!T) { - copy((&source)[0 .. 1], (&target)[0 .. 1]); + tanya.memory.op.copy((&source)[0 .. 1], (&target)[0 .. 1]); static if (hasElaborateCopyConstructor!T || hasElaborateDestructor!T) { @@ -273,3 +275,53 @@ void swap(T)(ref T a, ref T b) @trusted assert(a == 5); assert(b == 3); } + +/** + * Copies the $(D_PARAM source) range into the $(D_PARAM target) range. + * + * Params: + * Source = Input range type. + * Target = Output range type. + * source = Source input range. + * target = Target output range. + * + * Precondition: $(D_PARAM target) should be large enough to accept all + * $(D_PARAM source) elements. + */ +void copy(Source, Target)(Source source, Target target) +if (isInputRange!Source && isOutputRange!(Target, Source)) +in +{ + static if (hasLength!Source && hasLength!Target) + { + assert(target.length >= source.length); + } +} +do +{ + alias E = ElementType!Source; + static if (isDynamicArray!Source + && is(Source == Target) + && !hasElaborateCopyConstructor!E + && !hasElaborateAssign!E) + { + tanya.memory.op.copy(source, target); + } + else + { + for (; !source.empty; source.popFront()) + { + put(target, source.front); + } + } +} + +/// +@nogc nothrow pure @safe unittest +{ + int[2] actual; + int[2] expected = [2, 3]; + + copy(actual[], expected[]); + assert(actual == expected); +} diff --git a/source/tanya/container/string.d b/source/tanya/container/string.d index a523d68..c6bc4e7 100644 --- a/source/tanya/container/string.d +++ b/source/tanya/container/string.d @@ -27,7 +27,7 @@ module tanya.container.string; import std.algorithm.comparison : cmp; -import std.algorithm.mutation : bringToFront, copy; +import std.algorithm.mutation : bringToFront; import std.algorithm.searching; import tanya.algorithm.comparison; import tanya.algorithm.mutation; diff --git a/source/tanya/math/mp.d b/source/tanya/math/mp.d index ae365de..5a1e49a 100644 --- a/source/tanya/math/mp.d +++ b/source/tanya/math/mp.d @@ -15,14 +15,13 @@ module tanya.math.mp; import std.algorithm.comparison : cmp; -import std.algorithm.mutation : copy, fill, reverse; +import std.algorithm.mutation : fill, reverse; import std.range; import tanya.algorithm.comparison; import tanya.algorithm.mutation; import tanya.container.array; import tanya.encoding.ascii; import tanya.memory; -static import tanya.memory.op; import tanya.meta.trait; import tanya.meta.transform; @@ -211,7 +210,7 @@ struct Integer this(this) @nogc nothrow pure @safe { auto tmp = allocator.resize!digit(null, this.size); - tanya.memory.op.copy(this.rep[0 .. this.size], tmp); + copy(this.rep[0 .. this.size], tmp); this.rep = tmp; } @@ -344,8 +343,7 @@ struct Integer if (is(Unqual!T == Integer)) { this.rep = allocator.resize(this.rep, value.size); - tanya.memory.op.copy(value.rep[0 .. value.size], - this.rep[0 .. value.size]); + copy(value.rep[0 .. value.size], this.rep[0 .. value.size]); this.size = value.size; this.sign = value.sign; diff --git a/source/tanya/memory/package.d b/source/tanya/memory/package.d index 7cf49e4..a98cf4a 100644 --- a/source/tanya/memory/package.d +++ b/source/tanya/memory/package.d @@ -14,7 +14,7 @@ */ module tanya.memory; -import std.algorithm.mutation; +import std.algorithm.mutation : uninitializedFill; import tanya.conv; import tanya.exception; public import tanya.memory.allocator;