If I try to use std.algorithm.fill(Range1, Range2)(Range1 range, Range2 filler), I keep getting the error message that no template match could be found. It looks like the compiler is trying to match with fill (Range, Value) rather than the other one.
auto test = new char[256];
fill(test, "abc".dup);
Is it not possible to fill a character array using fill?
The error
test.d(13): Error: template
std.algorithm.fill(Range,Value) if
(isForwardRange!(Range) &&
is(typeof(range.front = filler))) does
not match any function template
declarationtest.d(13): Error:
template
std.algorithm.fill(Range,Value) if
(isForwardRange!(Range) &&
is(typeof(range.front = filler)))
cannot deduce t emplate function from
argument types !()(char[],char[])
std.algorithm.filltakes a range. All string types are ranges ofdchar. This is because they’re all unicode.charis a UTF-8 code unitwcharis a UTF-16 code unit, anddcharis a UTF-32 code unit. Multiple code units make up a code point, which is a character. For UTF-8, a code point could be up to 6 code units. For UTF-16, it could be up to 2. For UTF-32, 1 code unit is always 1 code point, so adcharis always guaranteed to be a valid character.charandwcharby themselves, however, are not guaranteed to be valid characters at all, and it’s generally a bug if you see an individualcharorwcharused. Multiplecharsorwcharsoften must be combined to make up a single character. So, you can’t deal withcharsorwcharsindividually. That’s why if you’re iterating over a string of any kind with foreach, you should always give its type asdchar.If you didn’t specify
dchar, then it would be whatever the character type ofstris, which would invariably cause bugs unlessstrwere an array ofdchar, because you’d end up with code units (pieces of characters) instead of code points (whole characters). Onlydcharscan be dealt with individually.It’s because of all of this that all string types and character arrays are considered to be ranges of
dchar, regardless of what their actual element types are. So, when you callpopFronton a string, it could pop off a lot more than just onecharorwchar. And if you callfront, it may have to decode multiplecharsorwcharsto return thedcharthat is the first character in the string. This means that you can’t treatcharorwchararrays as being random access. The 4th character could be the 4th element, or it could be the 12th. And regardless of which index it starts at, it could be multiple code units long, so you can’t just grab a random index incharorwchararray and expect it to be valid. So, arrays ofcharandwcharare not random access ranges. They’re not output ranges either.Think about it. Let’s take the character
'\U00010143'() for instance. It has a code unit length of 4 for UTF-8 and 2 for UTF-16. You can’t just fill any randomcharorwchararray with it. If it’s achararray, and its length isn’t a multiple of 4, then the last () isn’t going to fit. If it’s awchararray, and its length isn’t a multiple of 2, then it’ll have the same problem. So, it really doesn’t work to use a function likefillon acharorwchararray.Now, it’ll work just fine with a
dchararray. Because a UTF-32 code unit is guaranteed to be a code point, every character in adchararray is one element, and it can be both a random access range and an output range. So, if you want to use a function likefillwith character arrays, you need to use an array ofdchar. You can usestd.conv.toto convert it to the type of character array that you want after that, but you can’t fill an array ofcharorwchardirectly.Arrays of
charandwcharwork great with algorithms which don’t need output ranges or random access ranges, but they don’t work with those. For those, you need arrays ofdchar.