Reflections on isPalindrome
H. S. Teoh via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Fri Oct 24 15:06:40 PDT 2014
On Fri, Oct 24, 2014 at 09:56:18PM +0000, "Nordlöw" via Digitalmars-d-learn wrote:
> I would appreciate comments on my palindrome predicate function
>
> bool isPalindrome(R)(in R range) @safe pure
> if (isBidirectionalRange!(R))
> {
> import std.range: retro, take;
> import std.algorithm: equal;
> static if (hasLength!R)
> {
> const mid = range.length/2; // too long for string
> return equal(range.retro.take(mid),
> range.take(mid));
> }
> else
> {
> return range.retro.equal(range);
> }
> }
[...]
I'd just do it the simple way using range primitives:
bool isPalindrome(R)(in R range)
if (isBidirectionalRange!R)
{
auto r = range.save;
while (!r.empty)
{
if (r.front != r.back)
return false;
r.popFront();
r.popBack();
}
return true;
}
This is guaranteed to work on all bidirectional ranges in single-pass,
handles odd/even lengths correctly, and doesn't depend on .length.
Offhand remark: in general you shouldn't annotate template functions
with @safe or pure. Instead, let the compiler infer those attributes,
and use @safe/pure unittests with known @safe/pure ranges to ensure your
code itself doesn't introduce any un- at safe or impure operations.
Otherwise, your function cannot be used with a range that has un- at safe
or impure range methods.
T
--
Государство делает вид, что платит нам зарплату, а мы делаем вид, что работаем.
More information about the Digitalmars-d-learn
mailing list