From 58eba76cc2393fc052c8647be84b22aa4bf04ed7 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Wed, 5 Jul 2017 18:25:02 +0300 Subject: [PATCH 1/2] Fix Issue 8472 - Replace walkLength() with an improved count() --- std/algorithm/searching.d | 15 ++++++++++----- std/range/primitives.d | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/std/algorithm/searching.d b/std/algorithm/searching.d index 72a6f341d39..157bd3932e5 100644 --- a/std/algorithm/searching.d +++ b/std/algorithm/searching.d @@ -696,11 +696,16 @@ size_t count(alias pred = "true", R)(R haystack) if (isInputRange!R && !isInfinite!R && is(typeof(unaryFun!pred(haystack.front)) : bool)) { - size_t result; - alias T = ElementType!R; //For narrow strings forces dchar iteration - foreach (T elem; haystack) - if (unaryFun!pred(elem)) ++result; - return result; + static if (hasLength!R && is(typeof(unary!fun(pred) == unary!fun("true")))) + return haystack.length; + else + { + size_t result; + alias T = ElementType!R; //For narrow strings forces dchar iteration + foreach (T elem; haystack) + if (unaryFun!pred(elem)) ++result; + return result; + } } @safe unittest diff --git a/std/range/primitives.d b/std/range/primitives.d index 7dc0d018a02..7f67418b5c4 100644 --- a/std/range/primitives.d +++ b/std/range/primitives.d @@ -1638,6 +1638,7 @@ upTo) steps have been taken and returns $(D upTo). Infinite ranges are compatible, provided the parameter $(D upTo) is specified, in which case the implementation simply returns upTo. */ +deprecated("use std.algorithm.searching.count instead.") auto walkLength(Range)(Range range) if (isInputRange!Range && !isInfinite!Range) { From 062948ffc29f788f4a1d8496279240739d200b87 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Wed, 5 Jul 2017 19:21:57 +0300 Subject: [PATCH 2/2] Fix documentation and add overload --- std/algorithm/searching.d | 23 ++++++++++++++--------- std/range/primitives.d | 32 +++++++++++++++----------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/std/algorithm/searching.d b/std/algorithm/searching.d index 157bd3932e5..25379b58504 100644 --- a/std/algorithm/searching.d +++ b/std/algorithm/searching.d @@ -692,20 +692,25 @@ if (isForwardRange!R1 && !isInfinite!R1 && } /// Ditto -size_t count(alias pred = "true", R)(R haystack) +size_t count(alias pred, R)(R haystack) if (isInputRange!R && !isInfinite!R && is(typeof(unaryFun!pred(haystack.front)) : bool)) { - static if (hasLength!R && is(typeof(unary!fun(pred) == unary!fun("true")))) + size_t result; + alias T = ElementType!R; //For narrow strings forces dchar iteration + foreach (T elem; haystack) + if (unaryFun!pred(elem)) ++result; + return result; +} + +/// Ditto +size_t count(R)(R haystack) +if (isInputRange!R && !isInfinite!R) +{ + static if (hasLength!R) return haystack.length; else - { - size_t result; - alias T = ElementType!R; //For narrow strings forces dchar iteration - foreach (T elem; haystack) - if (unaryFun!pred(elem)) ++result; - return result; - } + return count!"true"(haystack); } @safe unittest diff --git a/std/range/primitives.d b/std/range/primitives.d index 7f67418b5c4..c1a139c136a 100644 --- a/std/range/primitives.d +++ b/std/range/primitives.d @@ -1625,45 +1625,43 @@ range. If $(D hasLength!Range), simply returns $(D range.length) without checking $(D upTo) (when specified). -Otherwise, walks the range through its length and returns the number -of elements seen. Performes $(BIGOH n) evaluations of $(D range.empty) +Otherwise, walks the range for $(D upTo) elements. If $(D range.length) is smaller +than $(D upTo), the walking stops returning $(D range.length). + +Performes $(BIGOH n) evaluations of $(D range.empty) and $(D range.popFront()), where $(D n) is the effective length of $(D range). -The $(D upTo) parameter is useful to "cut the losses" in case -the interest is in seeing whether the range has at least some number -of elements. If the parameter $(D upTo) is specified, stops if $(D -upTo) steps have been taken and returns $(D upTo). - Infinite ranges are compatible, provided the parameter $(D upTo) is specified, in which case the implementation simply returns upTo. */ -deprecated("use std.algorithm.searching.count instead.") -auto walkLength(Range)(Range range) -if (isInputRange!Range && !isInfinite!Range) +auto walkLength(Range)(Range range, const size_t upTo) +if (isInputRange!Range) { static if (hasLength!Range) return range.length; + else static if (isInfinite!Range) + return upTo; else { size_t result; - for ( ; !range.empty ; range.popFront() ) + for ( ; result < upTo && !range.empty ; range.popFront() ) ++result; return result; } } -/// ditto -auto walkLength(Range)(Range range, const size_t upTo) -if (isInputRange!Range) + +//@@@DEPRECATED_2018-07@@@ +deprecated("use std.algorithm.searching.count instead.") +auto walkLength(Range)(Range range) +if (isInputRange!Range && !isInfinite!Range) { static if (hasLength!Range) return range.length; - else static if (isInfinite!Range) - return upTo; else { size_t result; - for ( ; result < upTo && !range.empty ; range.popFront() ) + for ( ; !range.empty ; range.popFront() ) ++result; return result; }