diff --git a/std/range/primitives.d b/std/range/primitives.d index 6862c5cd8..316c5c6ab 100644 --- a/std/range/primitives.d +++ b/std/range/primitives.d @@ -1750,6 +1750,20 @@ if (isInputRange!Range && !isInfinite!Range) else { size_t result; + static if (autodecodeStrings && isNarrowString!Range) + { + import std.utf : codeUnitLimit; + result = range.length; + foreach (const i, const c; range) + { + if (c >= codeUnitLimit!Range) + { + result = i; + break; + } + } + range = range[result .. $]; + } for ( ; !range.empty ; range.popFront() ) ++result; return result; @@ -1766,6 +1780,20 @@ if (isInputRange!Range) else { size_t result; + static if (autodecodeStrings && isNarrowString!Range) + { + import std.utf : codeUnitLimit; + result = upTo > range.length ? range.length : upTo; + foreach (const i, const c; range[0 .. result]) + { + if (c >= codeUnitLimit!Range) + { + result = i; + break; + } + } + range = range[result .. $]; + } for ( ; result < upTo && !range.empty ; range.popFront() ) ++result; return result; diff --git a/std/utf.d b/std/utf.d index 1849726b0..4a093cc7c 100644 --- a/std/utf.d +++ b/std/utf.d @@ -1410,7 +1410,8 @@ do assert(str.decodeBack(i) == 'å' && i == 2 && str.empty); } -// Gives the maximum value that a code unit for the given range type can hold. +// For the given range, code unit values less than this +// are guaranteed to be valid single-codepoint encodings. package template codeUnitLimit(S) if (isSomeChar!(ElementEncodingType!S)) {