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-@safe or impure operations. Otherwise, your function cannot be used with a range that has un-@safe or impure range methods. T -- Государство делает вид, что платит нам зарплату, а мы делаем вид, что работаем.