digitalmars.D.learn - Swap front for char[] input ranges
- RazvanN (23/23) Dec 19 2016 Hi,
- Basile B. (5/28) Dec 19 2016 does it work if you cast the 2 char[] as 2 ubyte[] ?
- =?UTF-8?Q?Ali_=c3=87ehreli?= (11/33) Dec 19 2016 Obivously, tmp1 and tmp2 are unusued there. :)
- RazvanN (7/32) Dec 19 2016 In this case, the bringToFront function [1] should not accept
- =?UTF-8?Q?Ali_=c3=87ehreli?= (46/82) Dec 19 2016 First, thanks to you and to your colleagues very much for improving D
- RazvanN (10/25) Dec 21 2016 No need to mention it. It is an honor to be able contribute
Hi, I have a function which accepts 2 input Ranges and swaps the first element in Range1 with the first element in Range2. The swapping code looks something like this : static if (is(typeof(swap(r1.front, r2.front)))) { swap(r1.front, r2.front); } else { auto t1 = moveFront(r1), t2 = moveFront(r2); auto tmp1 = r1.front; auto tmp2 = r2.front; r1.front = move(t2); r2.front = move(t1); } This code works for most cases, except when 2 char[] are passed. In that case, the compilation fails with error messages which state that r1.front and r2.front are not Lvalues. So, my question is: how can I swap the 2 elements since in the case of char[] input ranges the front property does not return a reference?
Dec 19 2016
On Monday, 19 December 2016 at 10:41:46 UTC, RazvanN wrote:Hi, I have a function which accepts 2 input Ranges and swaps the first element in Range1 with the first element in Range2. The swapping code looks something like this : static if (is(typeof(swap(r1.front, r2.front)))) { swap(r1.front, r2.front); } else { auto t1 = moveFront(r1), t2 = moveFront(r2); auto tmp1 = r1.front; auto tmp2 = r2.front; r1.front = move(t2); r2.front = move(t1); } This code works for most cases, except when 2 char[] are passed. In that case, the compilation fails with error messages which state that r1.front and r2.front are not Lvalues. So, my question is: how can I swap the 2 elements since in the case of char[] input ranges the front property does not return a reference?does it work if you cast the 2 char[] as 2 ubyte[] ? If so, it's a problem with narrow strings and utf8 decoding...i.e there's no guarantee that each code unit in r1 matches to a code unit in r2.
Dec 19 2016
On 12/19/2016 02:41 AM, RazvanN wrote:Hi, I have a function which accepts 2 input RangesAs your comments make it clear below, they cannot be InputRanges.and swaps the first element in Range1 with the first element in Range2. The swapping code looks something like this : static if (is(typeof(swap(r1.front, r2.front)))) { swap(r1.front, r2.front); } else { auto t1 = moveFront(r1), t2 = moveFront(r2); auto tmp1 = r1.front; auto tmp2 = r2.front;Obivously, tmp1 and tmp2 are unusued there. :)r1.front = move(t2); r2.front = move(t1); } This code works for most cases, except when 2 char[] are passed. In that case, the compilation fails with error messages which state that r1.front and r2.front are not Lvalues. So, my question is: how can I swap the 2 elements since in the case of char[] input ranges the front property does not return a reference?Not possible... It's ok to use something similar to the following template constraint: void foo(R1, R2)(R1 r1, R2 r2) if ((hasSwappableElements!R1 && hasSwappableElements!R2) || (hasLvalueElements!R1 && hasLvalueElements!R2)) { // ... } Ali
Dec 19 2016
On Monday, 19 December 2016 at 12:25:02 UTC, Ali Çehreli wrote:On 12/19/2016 02:41 AM, RazvanN wrote:In this case, the bringToFront function [1] should not accept char[] as parameters? Or a special path should be added in the function, so that char[] are treated specially? [1] http://dlang.org/phobos/std_algorithm_mutation.html#bringToFront[...]As your comments make it clear below, they cannot be InputRanges.[...]swapping code[...]Obivously, tmp1 and tmp2 are unusued there. :)[...]passed.[...]state[...]is:[...]input ranges[...]Not possible... It's ok to use something similar to the following template constraint: void foo(R1, R2)(R1 r1, R2 r2) if ((hasSwappableElements!R1 && hasSwappableElements!R2) || (hasLvalueElements!R1 && hasLvalueElements!R2)) { // ... } Ali
Dec 19 2016
On 12/19/2016 06:09 AM, RazvanN wrote:On Monday, 19 December 2016 at 12:25:02 UTC, Ali Çehreli wrote:First, thanks to you and to your colleagues very much for improving D with these fixes. :) I think you're working on the following bug: https://issues.dlang.org/show_bug.cgi?id=16959 Regarding the compilation error inside swapFront, its template constraints should be fixed as I suggested earlier. It cannot work with any two InputRanges. I think it warrants its separate bug. private void swapFront(R1, R2)(R1 r1, R2 r2) if (isInputRange!R1 && isInputRange!R2) { static if (is(typeof(swap(r1.front, r2.front)))) { swap(r1.front, r2.front); } else { auto t1 = moveFront(r1), t2 = moveFront(r2); r1.front = move(t2); r2.front = move(t1); } } Regarding bringToFront: 1) Reading its documentation, bringToFront() seems to be an algorithms that mutates its ranges (not just give a brought-to-front view of existing data). If so, its argument cannot simply be an InputRange because there are InputRanges out there where you cannot write it their .front. (char[] is just one example.): size_t bringToFront(Range1, Range2)(Range1 front, Range2 back) if (isInputRange!Range1 && isForwardRange!Range2) { // ... } Its template constraint must also be changed to include a combination of hasLvalueElements() and hasMobileElements(). 2) After fixing that, a char[] can indeed bring characters to front but it would be an expensive operation where a multi-byte Unicode character would necessarily move a single-byte Unicode character to the right. (Additionally, depending on its length, the first argument may allow only a partial UTF-8 encoding at its end. Fail! :) ) I don't know how to allow or encode such an expensive operation which is outside the documented "Ο(max(front.length, back.length))" complexity of bringToFront(). If it were me, I would look for possibilities to change the behavior and make bringToFront() a non-mutating algorithm. What do others think? AliOn 12/19/2016 02:41 AM, RazvanN wrote:In this case, the bringToFront function [1] should not accept char[] as parameters? Or a special path should be added in the function, so that char[] are treated specially? [1] http://dlang.org/phobos/std_algorithm_mutation.html#bringToFront[...]As your comments make it clear below, they cannot be InputRanges.[...]swapping code[...]Obivously, tmp1 and tmp2 are unusued there. :)[...]passed.[...]state[...]is:[...]input ranges[...]Not possible... It's ok to use something similar to the following template constraint: void foo(R1, R2)(R1 r1, R2 r2) if ((hasSwappableElements!R1 && hasSwappableElements!R2) || (hasLvalueElements!R1 && hasLvalueElements!R2)) { // ... } Ali
Dec 19 2016
On Monday, 19 December 2016 at 20:26:26 UTC, Ali Çehreli wrote:On 12/19/2016 06:09 AM, RazvanN wrote:No need to mention it. It is an honor to be able contribute to this great language.[...]wrote:InputRanges.[...]following[...][...]char[][...]function, so[...]http://dlang.org/phobos/std_algorithm_mutation.html#bringToFront [...][...]That is right, I am working on that particular bug. After talking with AndreiA, I submitted this PR [1]. It treats the case of char[], but I am not really sure how the constraints should be applied to the function since it seems there are a lot of combinations (especially if char[] is supported). [1] https://github.com/dlang/phobos/pull/4970
Dec 21 2016