From deb11e97e253580535dc0b09386c6131b272767c Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Fri, 29 Dec 2017 00:01:44 +0100 Subject: [PATCH 1/3] Markdownify find --- std/algorithm/searching.d | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/std/algorithm/searching.d b/std/algorithm/searching.d index 03010db544e..61b987d292c 100644 --- a/std/algorithm/searching.d +++ b/std/algorithm/searching.d @@ -2296,8 +2296,8 @@ forward range with elements comparable with elements in Returns: A tuple containing `haystack` positioned to match one of the -needles and also the 1-based index of the matching element in $(D -needles) (0 if none of `needles` matched, 1 if `needles[0]` +needles and also the 1-based index of the matching element in +`needles` (0 if none of `needles` matched, 1 if `needles[0]` matched, 2 if `needles[1]` matched...). The first needle to be found will be the one that matches. If multiple needles are found at the same spot in the range, then the shortest one is the one which matches @@ -2306,11 +2306,11 @@ same spot in the range, then the shortest one is the one which matches matches). The relationship between `haystack` and `needles` simply means -that one can e.g. search for individual `int`s or arrays of $(D -int)s in an array of `int`s. In addition, if elements are +that one can e.g. search for individual `int`s or arrays of +`int`s in an array of `int`s. In addition, if elements are individually comparable, searches of heterogeneous types are allowed -as well: a `double[]` can be searched for an `int` or a $(D -short[]), and conversely a `long` can be searched for a `float` +as well: a `double[]` can be searched for an `int` or a +`short[]`, and conversely a `long` can be searched for a `float` or a `double[]`. This makes for efficient searches without the need to coerce one side of the comparison into the other's side type. From 3ab466b48c7fd89ba573abbde73d3aaabbddf2dd Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sun, 24 Dec 2017 11:42:48 +0100 Subject: [PATCH 2/3] `std.algorithm.searching.find` returns a named tuple For variadic overloads `std.algorithm.searching.find` will return a named tuple tuple instead of an anonymous tuple. --- changelog/std-algorithm-searching-find.dd | 11 +++++++++++ std/algorithm/searching.d | 21 ++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 changelog/std-algorithm-searching-find.dd diff --git a/changelog/std-algorithm-searching-find.dd b/changelog/std-algorithm-searching-find.dd new file mode 100644 index 00000000000..14039816494 --- /dev/null +++ b/changelog/std-algorithm-searching-find.dd @@ -0,0 +1,11 @@ +`std.algorithm.searching.find` returns a named tuple + +For variadic overloads $(REF find, std,algorithm,searching) will +return a named tuple tuple instead of an anonymous tuple: + +--- +import std.algorithm.searching : find; +auto t = find(a, 2, 4); +assert(t.haystack == [4, 2, 3]); +assert(t.needle == 2); +--- diff --git a/std/algorithm/searching.d b/std/algorithm/searching.d index 61b987d292c..621395dd39b 100644 --- a/std/algorithm/searching.d +++ b/std/algorithm/searching.d @@ -2295,8 +2295,8 @@ forward range with elements comparable with elements in Returns: -A tuple containing `haystack` positioned to match one of the -needles and also the 1-based index of the matching element in +A `Tuple!("haystack", "needle")` containing `haystack` positioned to match one of the +needles and also `needle`, the 1-based index of the matching element in `needles` (0 if none of `needles` matched, 1 if `needles[0]` matched, 2 if `needles[1]` matched...). The first needle to be found will be the one that matches. If multiple needles are found at the @@ -2320,7 +2320,7 @@ is considered to be 1.) The strategy used in searching several subranges at once maximizes cache usage by moving in `haystack` as few times as possible. */ -Tuple!(Range, size_t) find(alias pred = "a == b", Range, Ranges...) +auto find(alias pred = "a == b", Range, Ranges...) (Range haystack, Ranges needles) if (Ranges.length > 1 && is(typeof(startsWith!pred(haystack, needles)))) { @@ -2329,7 +2329,7 @@ if (Ranges.length > 1 && is(typeof(startsWith!pred(haystack, needles)))) size_t r = startsWith!pred(haystack, needles); if (r || haystack.empty) { - return tuple(haystack, r); + return tuple!("haystack", "needle")(haystack, r); } } } @@ -2338,16 +2338,27 @@ if (Ranges.length > 1 && is(typeof(startsWith!pred(haystack, needles)))) @safe unittest { import std.typecons : tuple; + int[] a = [ 1, 4, 2, 3 ]; + // Non-variadic find (returns just the haystack) assert(find(a, 4) == [ 4, 2, 3 ]); assert(find(a, [ 1, 4 ]) == [ 1, 4, 2, 3 ]); - assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2)); + + // Variadic find (returns haystack + range) + auto t = find(a, 2, 4); + assert(t.haystack == [4, 2, 3]); + assert(t.needle == 2); + // Mixed types allowed if comparable + assert(find(a, [ 1, 3 ], 4) == tuple([ 4, 2, 3 ], 2)); assert(find(a, 5, [ 1.2, 3.5 ], 2.0) == tuple([ 2, 3 ], 3)); } +/// @safe unittest { + import std.typecons : tuple; + auto s1 = "Mary has a little lamb"; assert(find(s1, "has a", "has an") == tuple("has a little lamb", 1)); assert(find(s1, 't', "has a", "has an") == tuple("has a little lamb", 2)); From 07d04cacbb89b421b4308553660e7e2e65ca8c82 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Sun, 24 Dec 2017 11:56:00 +0100 Subject: [PATCH 3/3] Fix CTFE Error: reinterpreting cast from inout(string)* std/typecons.d(648): Error: reinterpreting cast from inout(string)* to inout(Tuple!(string, ulong))* is not supported in CTFE std/algorithm/searching.d(2538): called from here: find(haystack, _param_1, _param_2)._Tuple_super() std/typecons.d(977): called from here: canFind("dat", "pos", k) std/algorithm/iteration.d(1148): called from here: __lambda1(front(this._input)) std/algorithm/iteration.d(1174): called from here: this.prime() std/typecons.d(978): called from here: FilterResult(["dat"], false, null).empty() std/typecons.d(978): while evaluating: static assert(FilterResult(["dat"], false, null).empty) std/typecons.d(1021): Error: template instance std.typecons.Tuple!(float, "dat", ulong[2], "pos").Tuple.rename!(["dat":"height"]) error instantiating std/typecons.d(1378): instantiated from here: Tuple!() --- std/algorithm/searching.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/algorithm/searching.d b/std/algorithm/searching.d index 621395dd39b..b4eee085d8a 100644 --- a/std/algorithm/searching.d +++ b/std/algorithm/searching.d @@ -2532,7 +2532,7 @@ template canFind(alias pred="a == b") allSatisfy!(isForwardRange, Ranges) && is(typeof(find!pred(haystack, needles)))) { - return find!pred(haystack, needles)[1]; + return find!pred(haystack, needles).needle; } }