in reply to [OT] Swapping buffers in place.
I think the idea expressed in the first reply, involving enough temp storage to hold the difference in size between the two parts, will have the smallest footprint that can be implemented by simply incrementing (or decrementing) pointers.
But if you really want to pursue a single-temp-register solution, the basic idea for the pointer arithmetic would go like this:
I hope I've got that right (I suspect there may be a better way to describe it)... If it all sounds like a better idea than using more storage, then have fun with that.
(Update: Regarding the "completion condition" (item 6), there is a better (more correct) description: it will always happen on an iteration where a value is moved out of the temp register. When D is odd, this happens only once, and when it's even, it happens exactly twice - once for the even-numbered offsets, and once for the odd-numbered ones.)
(Another update -- sorry... The problem in steps 5 and 6 is not just an even/odd thing. It has to do with the largest common divisor of D and buffer_count; e.g. if D and buffer_count are both multiples of 4, then you'll need to move values out of the temp register a total of four times; you'll need to add 1 to the pointers after the first three of those, and the fourth one will be the final iteration.)
Can't... stop... updating... I improved the phrasing in step 3 (I hope it's clearer), and here is a diagram of the sequence (using a small buffer).
So, in addition to the temp register, you need to store the memory address from which a value was last moved into TR; when the "move-from" pointer (P2) is set to that address, you have to move the value from TR, instead of from P2, then increment P1 and P2, move from P1 to TR, and then resume.
TR 0 1 2 3 4 5 6 7 8 9 [x x x x][y y y y y y] 0. _/ A B C D E F G H I J *P1 *P2 set pointers, bgn=0 1. A/ A B C D E F G H I J *P1 -> TR 2. A/ E B C D E F G H I J *P2 -> *P1 *P1 *P2 shift pointers 3. A/ E B C D I F G H I J *P2 -> *P1 *P2 *P1 shift pointers 4. A/ E B C D I F G H C J *P2 -> *P1 *P1 *P2 shift pointers 5. A/ E B G D I F G H C J *P2 -> *P1 *P2 *P1 shift pointers (now P2 points to "bgn" location (0), so fetch from TR:) 6. A/ E B G D I F A H C J TR -> *P1 *P2 *P1 increment pointers, bgn=7 7. H/ E B G D I F A H C J *P1 -> TR 8. H/ E B G D I F A B C J *P2 -> *P1 *P1 *P2 shift pointers 9. H/ E F G D I F A B C J *P2 -> *P1 *P1 *P2 shift pointers 10. H/ E F G D I J A B C J *P2 -> *P1 *P2 *P1 shift pointers 11, H/ E F G D I J A B C D *P2 -> *P1 *P1 *P2 (now P2 points to "bgn" location (7), so fetch from TR:) 12. H/ E F G H I J A B C D TR -> *P1 (last iteration) [y y y y y y][x x x x]
|
---|