On 01/29/2013 09:20 PM, monarch_dodra wrote:
On Tuesday, 29 January 2013 at 19:44:23 UTC, Robert Schadek wrote:
Hi,
I have a Deque implementation that I really like. I would like to get
some comments on it.
http://dpaste.1azy.net/4bf119e7 dpaste does not run the unittests
successfully. I don't
know why. I tested on a x32 as well as x64 machine and it works on both.
Best Regards
Robert
Appart from the fact you seem to have copy pasted your code twice,
here are a quick comments, interface wise. I didn't check anything
implementation-wise
fixed
1. When you put a unittest inside the definition of a class/struct, it
gets run for every instantiation of said class, and has access to "T".
This is good for writing generic tests for the current T type. This
can be useful to test things that depend on T, such as making sure
some functions are indeed safe, or whatnot.
If you are testing a specific implementation, then move it out of the
struct.
For example:
//----
import std.stdio;
struct S(T)
{
unittest
{
//Tests S!T for every T.
writeln("Unittest: S!", T.stringof);
}
}
unittest
{
//Write a specific S!int test here, for example
writeln("Unittest: Global");
}
void main()
{
alias A = S!int; //Force S!int tests
alias B = S!double; //Force S!int tests
}
//----
"rdmd -unittest main.d" produces:
//----
Unittest: Global
Unittest: S!int
Unittest: S!double
//----
I see the point. I will fix that.
2. Nitpick: I'd personally prefer you use the term "Range" for your
iterator. Iterator != Range. You are confusing me. Also, I'd consider
nesting the iterator definition inside your deque.
That on my list as well.
3. Nitpick: Don't use parenthesis for single arg templates:
No: "Deque!(int)"
yes: "Deque!int"
May I ask why? Both are correct after all. Or is it just the preferred
style?
4. Why does your iterator have two template parameters? Seems it is
always "T" and "Deque!T". Why bother with the second parameter at all?
If you place it inside your Deque implementation, then it becomes
parameter-less (appart from the implicit T of course). The added
advantage is that it becomes a "Deque!int.Iterator" type. This is good
if you ever write "List", and don't want to have the name "Iterator"
clash...
I did this to return a Iterator from a const(Deque). But placing it
nested is the better and prettier way.
5. Users expect "opSlice()" to produce an actual range. You are using
it to deep copy the deck. This goes against your comment in regards to
slicing an iterator. Just have your "opSlice()" do the same as what
"range()" does, and get rid of "range()". This is the usage I'd expect:
//----
Deque!int de = ... ;
Iterator!int it = de[];
writeln(it);
//----
I submitted a bug report for sort recently (9091 became 8368).
monarchdodra said (and pointed to source) that opSlice should return the
same type in respect to the called object.
I'll review the actual deque implementation tomorrow.
Thanks