Skip to content

Commit 09304d7

Browse files
wilzbachRazvanN7
authored andcommitted
Add isSliceOf to check the origin of a slice
1 parent b22224d commit 09304d7

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

changelog/std-array-sliceOf.dd

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
std.array.sliceOf has been added
2+
3+
$(REF sliceOf, std,array) provides a `@safe` way to query
4+
5+
---
6+
import std.array : sliceOf;
7+
8+
auto a = [1, 2, 3, 4, 5];
9+
10+
assert(a[3..$].sliceOf(a));
11+
assert(a[].sliceOf(a));
12+
assert(!a.sliceOf(a[3..$]));
13+
assert(![7, 8].sliceOf(a));
14+
assert(!null.sliceOf(a));
15+
16+
// null is a slice of itself
17+
assert(null.sliceOf(null));
18+
---

std/array.d

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ $(TR $(TH Function Name) $(TH Description)
5959
$(TD Checks if the final segments of two arrays refer to the same place
6060
in memory.
6161
))
62+
$(TR $(TD $(LREF isSliceOf))
63+
$(TD Checks if the first array is a slice of the second array.
64+
))
6265
$(TR $(TD $(LREF split))
6366
$(TD Eagerly split a range or string into an array.
6467
))
@@ -1813,6 +1816,84 @@ pure nothrow @nogc bool sameTail(T)(in T[] lhs, in T[] rhs)
18131816
}}
18141817
}
18151818

1819+
/**
1820+
Checks whether a `part` is part of a `whole` array.
1821+
1822+
Params:
1823+
1824+
part = The array to check for its origin
1825+
whole = The origin array to be queried
1826+
1827+
Returns: `true` if `part` is a slice of `whole`.
1828+
*/
1829+
bool isSliceOf(T)(const scope T[] part, const scope T[] whole) @trusted
1830+
{
1831+
return whole.ptr <= part.ptr &&
1832+
part.ptr + part.length <= whole.ptr + whole.length;
1833+
}
1834+
1835+
///
1836+
@safe pure nothrow unittest
1837+
{
1838+
auto a = [1, 2, 3, 4, 5];
1839+
1840+
assert(a[3..$].isSliceOf(a));
1841+
assert(a[].isSliceOf(a));
1842+
assert(!a.isSliceOf(a[3..$]));
1843+
assert(![7, 8].isSliceOf(a));
1844+
assert(!null.isSliceOf(a));
1845+
1846+
// null is a slice of itself
1847+
assert(null.isSliceOf(null));
1848+
}
1849+
1850+
@safe pure nothrow unittest
1851+
{
1852+
static foreach (T; AliasSeq!(int[], const(int)[], immutable(int)[], const int[], immutable int[]))
1853+
{{
1854+
T a = [1, 2, 3, 4, 5];
1855+
T b = a;
1856+
T c = a[1 .. $];
1857+
T d = a[0 .. 1];
1858+
T e = null;
1859+
1860+
assert(a.isSliceOf(a));
1861+
assert(b.isSliceOf(a));
1862+
assert(a.isSliceOf(b));
1863+
1864+
assert(c.isSliceOf(a));
1865+
assert(c.isSliceOf(b));
1866+
assert(!a.isSliceOf(c));
1867+
assert(!b.isSliceOf(c));
1868+
1869+
assert(d.isSliceOf(a));
1870+
assert(d.isSliceOf(b));
1871+
assert(!a.isSliceOf(d));
1872+
assert(!b.isSliceOf(d));
1873+
1874+
assert(!e.isSliceOf(a));
1875+
assert(!e.isSliceOf(b));
1876+
assert(!e.isSliceOf(c));
1877+
assert(!e.isSliceOf(d));
1878+
1879+
//verifies R-value compatibilty
1880+
assert(a[$ .. $].isSliceOf(a));
1881+
assert(a[0 .. 0].isSliceOf(a));
1882+
assert(a.isSliceOf(a[0.. $]));
1883+
assert(a[0 .. $].isSliceOf(a));
1884+
}}
1885+
}
1886+
1887+
// null is a slice of itself
1888+
@safe pure nothrow unittest
1889+
{
1890+
assert(null.isSliceOf(null));
1891+
1892+
int[] arr;
1893+
assert(null.isSliceOf(arr));
1894+
assert(arr.isSliceOf(null));
1895+
}
1896+
18161897
/**
18171898
Params:
18181899
s = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)

0 commit comments

Comments
 (0)