mirror of
https://github.com/dlang/phobos.git
synced 2025-05-11 23:05:34 +03:00
Merge pull request #4263 from wilzbach/infer_type_for_make_array_with_ranges
infer elementType for ranges in makeArray,makeSlice
This commit is contained in:
commit
9a00cb53e7
2 changed files with 73 additions and 6 deletions
|
@ -737,13 +737,21 @@ unittest
|
|||
test(theAllocator);
|
||||
}
|
||||
|
||||
/// Ditto
|
||||
Unqual!(ElementEncodingType!R)[] makeArray(Allocator, R)(auto ref Allocator alloc, R range)
|
||||
if (isInputRange!R && !isInfinite!R)
|
||||
{
|
||||
alias T = Unqual!(ElementEncodingType!R);
|
||||
return makeArray!(T, Allocator, R)(alloc, range);
|
||||
}
|
||||
|
||||
/// Ditto
|
||||
T[] makeArray(T, Allocator, R)(auto ref Allocator alloc, R range)
|
||||
if (isInputRange!R && !isInfinite!R)
|
||||
{
|
||||
static if (isForwardRange!R || hasLength!R)
|
||||
{
|
||||
static if (hasLength!R)
|
||||
static if (hasLength!R || isNarrowString!R)
|
||||
immutable length = range.length;
|
||||
else
|
||||
immutable length = range.save.walkLength;
|
||||
|
@ -763,10 +771,18 @@ if (isInputRange!R && !isInfinite!R)
|
|||
alloc.deallocate(m);
|
||||
}
|
||||
|
||||
for (; !range.empty; range.popFront, ++i)
|
||||
import std.conv : emplace;
|
||||
static if (isNarrowString!R || isRandomAccessRange!R)
|
||||
{
|
||||
import std.conv : emplace;
|
||||
cast(void) emplace!T(result.ptr + i, range.front);
|
||||
foreach (j; 0 .. range.length)
|
||||
{
|
||||
cast(void) emplace!T(result.ptr + i++, range[j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; !range.empty; range.popFront, ++i)
|
||||
cast(void) emplace!T(result.ptr + i, range.front);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -826,12 +842,40 @@ unittest
|
|||
a = alloc.makeArray!long([5, 42]);
|
||||
assert(a.length == 2);
|
||||
assert(a == [ 5, 42]);
|
||||
|
||||
// we can also infer the type
|
||||
auto b = alloc.makeArray([4.0, 2.0]);
|
||||
static assert(is(typeof(b) == double[]));
|
||||
assert(b == [4.0, 2.0]);
|
||||
}
|
||||
import std.experimental.allocator.gc_allocator : GCAllocator;
|
||||
test(GCAllocator.instance);
|
||||
test(theAllocator);
|
||||
}
|
||||
|
||||
// infer types for strings
|
||||
unittest
|
||||
{
|
||||
void test(A)(auto ref A alloc)
|
||||
{
|
||||
auto c = alloc.makeArray("fooπ😜");
|
||||
static assert(is(typeof(c) == char[]));
|
||||
assert(c == "fooπ😜");
|
||||
|
||||
auto d = alloc.makeArray("fooπ😜"d);
|
||||
static assert(is(typeof(d) == dchar[]));
|
||||
assert(d == "fooπ😜");
|
||||
|
||||
auto w = alloc.makeArray("fooπ😜"w);
|
||||
static assert(is(typeof(w) == wchar[]));
|
||||
assert(w == "fooπ😜");
|
||||
}
|
||||
|
||||
import std.experimental.allocator.gc_allocator : GCAllocator;
|
||||
test(GCAllocator.instance);
|
||||
test(theAllocator);
|
||||
}
|
||||
|
||||
version(unittest)
|
||||
{
|
||||
private struct ForcedInputRange
|
||||
|
|
|
@ -643,6 +643,16 @@ auto makeSlice(T,
|
|||
return .makeSlice!(T, replaceArrayWithPointer, Allocator)(alloc, [lengths]);
|
||||
}
|
||||
|
||||
/// ditto
|
||||
auto makeSlice(
|
||||
Flag!`replaceArrayWithPointer` replaceArrayWithPointer = Yes.replaceArrayWithPointer,
|
||||
Allocator,
|
||||
size_t N, Range)(auto ref Allocator alloc, auto ref Slice!(N, Range) slice)
|
||||
{
|
||||
alias T = Unqual!(slice.DeepElemType);
|
||||
return makeSlice!(T, replaceArrayWithPointer)(alloc, slice);
|
||||
}
|
||||
|
||||
/// ditto
|
||||
auto makeSlice(T,
|
||||
Flag!`replaceArrayWithPointer` replaceArrayWithPointer = Yes.replaceArrayWithPointer,
|
||||
|
@ -702,7 +712,7 @@ auto makeSlice(T,
|
|||
|
||||
// makes duplicate using `makeSlice`
|
||||
tup.slice[0, 0, 0] = 3;
|
||||
auto dup = makeSlice!int(Mallocator.instance, tup.slice);
|
||||
auto dup = makeSlice(Mallocator.instance, tup.slice);
|
||||
assert(dup.slice == tup.slice);
|
||||
|
||||
Mallocator.instance.dispose(tup.array);
|
||||
|
@ -715,12 +725,25 @@ auto makeSlice(T,
|
|||
import std.experimental.allocator;
|
||||
import std.experimental.allocator.mallocator;
|
||||
|
||||
auto tup = makeSlice!int(Mallocator.instance, [2, 3, 4], 10);
|
||||
auto tup = makeSlice(Mallocator.instance, [2, 3, 4], 10);
|
||||
auto slice = tup.slice;
|
||||
assert(slice[1, 1, 1] == 10);
|
||||
Mallocator.instance.dispose(tup.array);
|
||||
}
|
||||
|
||||
|
||||
@nogc unittest
|
||||
{
|
||||
import std.experimental.allocator;
|
||||
import std.experimental.allocator.mallocator;
|
||||
|
||||
// cast to your own type
|
||||
auto tup = makeSlice!double(Mallocator.instance, [2, 3, 4], 10);
|
||||
auto slice = tup.slice;
|
||||
assert(slice[1, 1, 1] == 10.0);
|
||||
Mallocator.instance.dispose(tup.array);
|
||||
}
|
||||
|
||||
/++
|
||||
Creates a common n-dimensional array from a slice.
|
||||
Params:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue