Implement proper iterators over atom pair in cell lists

I replaced the array of atom pairs with an iterator over atom pairs.

To do this using generators would be trivial (more or less)

   for icell, jcell in cell_neighbors:
        for iatom in cell_iterator(icell):
            for jatom in cell_iterator(jcell):
                yield iatom, jatom

Unfortunately c++ doesn't have co-routines, so I basically had to invert the triple loop.   It turned out to be ugly, but it works.

upsides
1. no need to build and store the full vector of atom pairs (less memory)
2. iterators are in-theory easier to work with. And more flexible in the long run.

downsides
1. it's currently a bit slower (44 seconds vs 41 seconds for a minimization of 1600 LJ atoms).  However, it's far from optimized.  I may be able to improve it.
2. the code is ugly as hell, confusing, and hard to debug.

What do you think, should we merge this PR?