RFC on range design for D2
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Wed Sep 10 11:38:49 PDT 2008
Sergey Gromov wrote:
> Bill Baxter <wbaxter at gmail.com> wrote:
>> Here's one from DinkumWare's <algorithm>:
>>
>> template<class _BidIt1,
>> class _BidIt2,
>> class _BidIt3> inline
>> _BidIt3 _Merge_backward(_BidIt1 _First1, _BidIt1 _Last1,
>> _BidIt2 _First2, _BidIt2 _Last2, _BidIt3 _Dest, _Range_checked_iterator_tag)
>> { // merge backwards to _Dest, using operator<
>> for (; ; )
>> if (_First1 == _Last1)
>> return (_STDEXT unchecked_copy_backward(_First2, _Last2, _Dest));
>> else if (_First2 == _Last2)
>> return (_STDEXT unchecked_copy_backward(_First1, _Last1, _Dest));
>> else if (_DEBUG_LT(*--_Last2, *--_Last1))
>> *--_Dest = *_Last1, ++_Last2;
>> else
>> *--_Dest = *_Last2, ++_Last1;
>> }
>>
>>
>> You can probably work around it some way, but basically it's using the
>> ability to ++ and -- on the same end as a sort of "peek next".
>
> They're using the ability to ++ and -- to avoid post-decrement at any
> cost. Otherwise it'd be just
>
>> else if (_DEBUG_LT(*_Last2, *_Last1))
>> *--_Dest = *_Last1--;
>> else
>> *--_Dest = *_Last2--;
>
> Now the same algorithm in ranges:
>
>> Merge_backward(R1, R2, R3)(R1 s1, R2 s2, R3 dst)
>> {
>> for (;;)
>> {
>> if (s1.isEmpty())
>> dst[] = s2[];
>> else if (s2.isEmpty())
>> dst[] = s1[];
>> else if (s1.last < s2.last)
>> {
>> dst.last = s1.last;
>> s1.shrink();
>> }
>> else
>> {
>> dst.last = s2.last;
>> s2.shrink();
>> }
>> dst.shrink();
>> }
>> }
>
> If there were shrink-on-read and (eureka!) shrink-on-write operations,
> it would be even shorter:
>
>> else if (s1.last < s2.last)
>> dst.putBack(s1.getBack());
>> else
>> dst.putBack(s2.getBack());
>
> where both getBack() and putBack() shrink the range from the end side.
Got to say I'm pretty much in awe :o). But (without thinking much about
it) I think the assignments dst[] = s1[] and dst[] = s2[] should be
replaced with calls to copy(retro(sx), retro(dst)). No?
Andrei
More information about the Digitalmars-d-announce
mailing list