220 33205 <CADw4SdREZTpyF84ZHkA=p+dMZ-V=0drdyTp_XVFPcWqUF=s0cA@mail.gmail.com> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Dan Raviv <dan.raviv@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: [idea for proposal] Adding std::shift to <algorithm>
Date: Fri, 14 Jul 2017 00:14:51 +0300
Lines: 433
Approved: news@gmane.org
Message-ID: <CADw4SdREZTpyF84ZHkA=p+dMZ-V=0drdyTp_XVFPcWqUF=s0cA@mail.gmail.com>
References: <bd1a5d3b-ccc1-44ab-91cc-a4d7195c9dc3@isocpp.org>
 <68bbd6d3-1578-43e1-b15f-563c9d6fb27c@isocpp.org> <c722a201-5c9c-4ac5-a1bd-e50beb6d7860@isocpp.org>
 <99d55051-ad56-4386-8a0f-9d7627b63106@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="001a11408742936e0e0554396de7"
X-Trace: blaine.gmane.org 1499980521 6000 195.159.176.226 (13 Jul 2017 21:15:21 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Thu, 13 Jul 2017 21:15:21 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBC5YJREBWAGRBYGFT7FQKGQEE7MLOWY@isocpp.org Thu Jul 13 23:15:15 2017
Return-path: <std-proposals+bncBC5YJREBWAGRBYGFT7FQKGQEE7MLOWY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-pg0-f70.google.com ([74.125.83.70])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBC5YJREBWAGRBYGFT7FQKGQEE7MLOWY@isocpp.org>)
	id 1dVlS6-00010i-AD
	for gclcip-std-proposals@m.gmane.org; Thu, 13 Jul 2017 23:15:14 +0200
Original-Received: by mail-pg0-f70.google.com with SMTP id g14sf71474799pgu.9
        for <gclcip-std-proposals@m.gmane.org>; Thu, 13 Jul 2017 14:15:14 -0700 (PDT)
ARC-Seal: i=2; a=rsa-sha256; t=1499980514; cv=pass;
        d=google.com; s=arc-20160816;
        b=G0fhu9VcrupMNuNQYI3NxUwxfwW5WqF3i3JJBW2xSw0PgQ3xuWHHILQbrfDu+3Pal4
         jOC+Pl0oY8y5w/BpV+MqzH8Tv9GFWnAKWTJ9eck+Z17Dbrd+nSc4Hpt9E8CufJlY2PNj
         okwCr7zd/mU3eZZAR7A+0hCcc9o4Q57Rgg3vkz6PNkPemdC2J8d9XvrDbaOsGsJmfpNS
         vjQJcwd/OC8SNr5JmeTecb0IPwNTp2X2jl+saHgK4U8z33ChioehQaBTr1yTiLXWDt8E
         7VQuBjPn0OcI4dI69mB3L/1X4Ezzgho4VcR+N3Mdbn0h9HUki39zjE84HCo6cm/mntRe
         ZkmQ==
ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post
         :list-id:mailing-list:precedence:reply-to:to:subject:message-id:date
         :from:references:in-reply-to:mime-version:arc-authentication-results
         :arc-message-signature:dkim-signature:arc-authentication-results;
        bh=j2YxV+LExRR/rYNWVYt3WUdi8fK7xC+NWQOncpB1FzA=;
        b=B+7NQrk6Ow5LEz62iXLiSn7HGNN4F6SFKOD8n3iKe6pjTS0vlcKlNyjMDTQpTik8FV
         +GrnvYIHuefDzp4YOQbPV7wD53q7N0LJT0Z1oIyRFU8ijEo/3aqrDep4W0ITFPX3yc84
         WvnIBbvsum5JcNtDlnTKCQ/4j0s5Mydto+CfxwuU8ok4EJzCL6Q2gqbg+qo0Qi0xysJq
         +9X61dqQea6W3DzM8HtK3f/5h3DPW6JY92uBSuPy9xtH+8dBkdh/q1rl1e8uv9lC6UwB
         FsrP6U8WP3TQdUXThxyA6zupeVMm952WNrajN3c/h+oplVOATOSOdVS3m2wuiyuQ+tUe
         Q7rw==
ARC-Authentication-Results: i=2; mx.google.com;
       dkim=pass header.i=@gmail.com header.b=CnEaWHMs;
       spf=pass (google.com: domain of dan.raviv@gmail.com designates 2607:f8b0:4003:c06::236 as permitted sender) smtp.mailfrom=dan.raviv@gmail.com;
       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=mime-version:in-reply-to:references:from:date:message-id:subject:to
         :x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=j2YxV+LExRR/rYNWVYt3WUdi8fK7xC+NWQOncpB1FzA=;
        b=xPoBpkLu12QV63caTdXMofF9H80ITbrwMjPiSL5ZLLLS/MGKyWkewhDxPyY2S8aSku
         PpczRLKJCu358pcIxT1a98gY+ccivL8kPi4tCLnO2rwHxzCotxd2aCD5Tmz8pm3513Qg
         feVx5G1byenuFSVKkhAi9suuTeCwJppMMRxbD3rayIlkALtldR6udjqTquB5IitRpEMd
         PhXgYOKFUKx2XPhDe0ZUUA4GCgm9KX8LQvkvqBobYaQ1IlnodzRV53bdbbCn76WUjlvb
         rf4s7qwbvHl2fZDbp7pxWevOfyrzxgEvbrVgkJPXxSGlLcjXKPfieetn4vJ+/AtvRIfP
         GcEw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:mime-version:in-reply-to:references:from:date
         :message-id:subject:to:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=j2YxV+LExRR/rYNWVYt3WUdi8fK7xC+NWQOncpB1FzA=;
        b=i7RC+CRZ6K1qaU7RJgWL7L48KF5fQn4IAm4k4ZRkklJJ64nkxxbA+2NjhXEkX1Gyxb
         nZcewnYHfpKHWQNNqI5joc2O7/Jsn5ZgvVrisxZMwZAgFczdaSYdrYAAlQaEQk5ZTfjq
         t8QqTfVDvGQ/dj1KqwzXMWtxG9WPAeZwS1SG0v6VYTrLjokAd57iRO7DBl1EEwE28fZa
         gEeWz3hdfShIE6dU+VlJO5Q0+o0EjjfbjJDEoxlCrmXdFdP+1jd9g+XPt4AA4naKNj2S
         NxvYJz8c71KtQg6RmdFbBz8vC+c4pGskDfiwH+1wEOTlo1gd/lfvflrPEsrQwSLYW/b7
         PKcw==
X-Gm-Message-State: AIVw110SODlNPQoJrvVEE3NuTzmlO93xrA8kaNIqq4sz6PVOCXCr4ALI
	IVQwZ7ddtp9scJTN
X-Received: by 10.99.37.193 with SMTP id l184mr7374229pgl.129.1499980514013;
        Thu, 13 Jul 2017 14:15:14 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.36.58.17 with SMTP id m17ls306550itm.16.canary-gmail; Thu, 13
 Jul 2017 14:15:12 -0700 (PDT)
X-Received: by 10.202.81.202 with SMTP id f193mr4509557oib.178.1499980512382;
        Thu, 13 Jul 2017 14:15:12 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1499980512; cv=none;
        d=google.com; s=arc-20160816;
        b=MfVU3xwSRyESHFMhsbTNCUpze6Z0wEHicGFFfulc2qicNxR61wtGcnMvbgI+oAbpGr
         qvJ9tsBIevDoNFGpvUT+/xKaU9r2dSJHwYc7KSWAZRFZ+yzgLZoK986RkBE+eloBd6ua
         DFSBeYz4kfaW1+kFVXpcUhN8jdQwN0AuyKqbE0tr3iUus5cbbj5DCrLAugAr69rey9FI
         NI+XL3uNqzEIowdk9/P3xOdTUi0NgSRnbEImx+gBj1N28RFo8kFbFeUBy/3aY45yk9aW
         Cr14M50dVFfQgoqMQwNNX2Rx+CPhYyJeC24AI6tcFcA9Nltt388vA20Cj6xHfdBQ/sIu
         uEHg==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=to:subject:message-id:date:from:references:in-reply-to:mime-version
         :dkim-signature:arc-authentication-results;
        bh=KPILW5V6NhAhoxjF20ZNoHiFXGzpRHtW1iLUsFz61L0=;
        b=VFn9w/wv04Hhf2G2L8h+6s5Wo2S3fAfY2ITQGG3bdRPB/6g9dpPGdcUQ2b6cqqx7aA
         Vz1wcXaD0W3i1+KM/hAN7yNDKt9e41KLsbdgJmoL99+7hsXZlcMIcN2G2vdT00MtIep0
         IkXh9qRvm/IQ/yvQ9pP380JS+8eCwvfC9u0FMIgwPMqVdcgXCSHebl9tCR0XubeI6PRb
         VCFABTxz1YrGXwKEDUbywgaQfIkNXA7GwcEFhvbtO6SJIYi2u80SA/KiTM0S5O7xuGfC
         VmeY2iZ5GO20JvhNIKRAFKd/eeaTulOtcxKVSzyxBAipx16QVd4Z94XjgQO7jK16etQR
         dfmA==
ARC-Authentication-Results: i=1; mx.google.com;
       dkim=pass header.i=@gmail.com header.b=CnEaWHMs;
       spf=pass (google.com: domain of dan.raviv@gmail.com designates 2607:f8b0:4003:c06::236 as permitted sender) smtp.mailfrom=dan.raviv@gmail.com;
       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com
Original-Received: from mail-oi0-x236.google.com (mail-oi0-x236.google.com. [2607:f8b0:4003:c06::236])
        by mx.google.com with ESMTPS id f195si5031100oih.311.2017.07.13.14.15.12
        for <std-proposals@isocpp.org>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Thu, 13 Jul 2017 14:15:12 -0700 (PDT)
Received-SPF: pass (google.com: domain of dan.raviv@gmail.com designates 2607:f8b0:4003:c06::236 as permitted sender) client-ip=2607:f8b0:4003:c06::236;
Original-Received: by mail-oi0-x236.google.com with SMTP id p188so56836720oia.0
        for <std-proposals@isocpp.org>; Thu, 13 Jul 2017 14:15:12 -0700 (PDT)
X-Received: by 10.202.231.143 with SMTP id e137mr3734429oih.189.1499980511796;
 Thu, 13 Jul 2017 14:15:11 -0700 (PDT)
Original-Received: by 10.74.71.207 with HTTP; Thu, 13 Jul 2017 14:14:51 -0700 (PDT)
In-Reply-To: <99d55051-ad56-4386-8a0f-9d7627b63106@isocpp.org>
X-Original-Sender: dan.raviv@gmail.com
X-Original-Authentication-Results: mx.google.com;       dkim=pass
 header.i=@gmail.com header.b=CnEaWHMs;       spf=pass (google.com: domain of
 dan.raviv@gmail.com designates 2607:f8b0:4003:c06::236 as permitted sender)
 smtp.mailfrom=dan.raviv@gmail.com;       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:33205
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/33205>

--001a11408742936e0e0554396de7
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Thu, Jul 13, 2017 at 8:21 PM, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:

> On Wednesday, July 12, 2017 at 6:43:11 PM UTC-7, Nicol Bolas wrote:
>>
>> On Wednesday, July 12, 2017 at 7:47:05 PM UTC-4, Arthur O'Dwyer wrote:
>>>
>>> On Wednesday, July 12, 2017 at 2:53:19 AM UTC-7, d...@soundradix.com
>>> wrote:
>>>>
>>>> Hi,
>>>>
>>>> Would anyone be interested in adding std::shift to <algorithm>?
>>>>
>>>> It would be similar to both:
>>>> - std::rotate, but without moving the head elements back to the tail.
>>>> This would allow a more efficient implementation and clearer semantics=
 in
>>>> case rotation is not needed as well as correctness in case rotation is
>>>> undesired.
>>>> - <algorithm>'s std::move/std::move_backward (depending on the shift
>>>> direction).
>>>>
>>>> std::shift should probably accommodate both left and right shifts by
>>>> one of:
>>>> - giving it either begin() and end(), or rbegin() and rend(), similar
>>>> to how std::rotate works for both left and right rotations. The advant=
age
>>>> is compactness of the implementation.
>>>> - allowing the shift count parameter to be either positive or negative=
..
>>>> The advantage is compactness, though it might not be clear which direc=
tion
>>>> is which - to be consistent with rotate, positive integers should shif=
t to
>>>> the left.
>>>> - having std::shift_right and std::shift_left functions. The advantage
>>>> is clarity when calling the methods, although the same argument could =
be
>>>> made for having separate std::rotate_left and std::rotate_right instea=
d of
>>>> std::rotate, which we don't have.
>>>>
>>>
>>> std::rotate is actually just a rotation; it doesn't need "left" or
>>> "right" qualification because they're 100% equivalent. Consider a class=
room
>>> globe with London in front, facing you. Now "rotate" the globe until
>>> Beijing is in front. It doesn't matter if you rotate left or rotate rig=
ht;
>>> the outcome is exactly the same either way.
>>>
>>>
>>>> Here's a sample implementation of a shift to the right direction:
>>>>
>>>> template<class BidirIt>
>>>> void shift_right(BidirIt first, BidirIt last, unsigned int n =3D 1)
>>>> {
>>>>     std::move_backward(first, last - n, last);
>>>> }
>>>>
>>>> This demonstrates that while std::shift is implementable with
>>>> std::move/std::move_backward,
>>>> 1) It isn't immediately clear from the code (at least to my eyes) that
>>>> this is a shift right, unless you are intimately familiar with
>>>> std::move_backward.
>>>> 2) Different calls, either to std::move or to std::move_backward, are
>>>> required, depending on the shift direction.
>>>>
>>>
>>> If you're shifting the whole container's contents, you could use either
>>> of these:
>>>     std::move(ctr.rbegin() + n, ctr.rend(), ctr.rbegin());
>>>     std::move_backward(ctr.begin(), ctr.end() - n, ctr.end())?
>>> I don't currently see the use-case for this "shift just a piece of a
>>> container" algorithm, I mean as distinct from std::move and
>>> std::move_backward which already exist. Do you have a use-case?
>>>
>>
>> The use-case would be anytime you'd want to use the code you just wrote.
>> When you have a range and N, and you want to do a shift N units in that
>> direction.
>>
>> The point of having it is one of clarification and user expectations.
>> Yes, you can use `move` and `move_backward` to accomplish a shift. But
>> consider the two function calls:
>>
>> //A
>> std::shift(rng.begin(), rng.end(), N);
>>
>> //B
>> auto rrng =3D std::make_reverse_range(rng);
>> std::move(rrng.begin() + N, rrng.end(), rrng.begin());
>>
>> A and B both do the same thing. But it's a *lot easier* to figure out
>> what the code is actually accomplishing from looking at A than B.
>>
>
> Do you have a use-case for either of these?
> I recall your admonition cross-thread that generally in the STL we *don't=
*
> want to operate on containers but rather on ranges (or iterator-pairs); s=
o
> if I had a range that I wanted to "shift", I would first consider whether=
 I
> could do something like
>
>     // OLD: shift_in_place(range, n); operate_on(range.begin(),
> range.end());
>     // NEW: operate_on(range.begin() + n, range.end());
>
> That is, instead of moving the actual data, which might be slow, I'd move
> one or the other "endpoint" while leaving the data in place.
> In his reply, Dan Raviv mentioned that this is exactly the kind of thing
> that a circular buffer does, and he's right (see proposal P0059).
>
> I also wrote that sometimes the circular buffer is less desirable than
just shifting the data.


>
> B gets even more obtuse confusing in a range-based world:
>>
>> //A
>> std::shift(rng, N);
>>
>> //B
>> auto rrng =3D std::make_reverse_range(rng);
>> std::move(std::make_range(rrng.begin + N, rrng.end()), rrng.begin());
>>
>
> In a range-based world, I would write this as
>
>     auto output =3D input | rng::drop(n);
>
> for a "left-shift", or... okay, the "right-shift" version is messy, at
> least in my version, because it involves concatenating ranges one of whic=
h
> needs to be created out of whole cloth, with n objects, each of which is =
in
> a "valid but unspecified" state.  (I'd bet *money* you can't give me a
> use-case for *that* one.)
>
> I'd still like to see a use-case for O(n) "shifting" a sequence of
> elements in-place (as opposed to using one of these range-based approache=
s,
> or using a circular buffer, or "shifting the endpoints").  I agree that
> sometimes you do want to copy/move the second part of a sequence over the
> first part, but I would always express that in terms of "I'm std::copy'in=
g
> / std::move'ing data." Expressing it as a "shift" doesn't feel natural to
> me in any of the (extremely rare) use-cases I've thought of. Do you have =
a
> use-case?
>
> Expressing a shift (either forward or backward) seems more natural to me
then copying or moving, which are generic operations, but require more
effort on the reader's part in case they are used for a simple shift. And
as I mentioned, a common use case in DSP for shifting is time series
analysis.


> =E2=80=93Arthur
>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/99d55051-ad56-4386-
> 8a0f-9d7627b63106%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/99d55051-ad=
56-4386-8a0f-9d7627b63106%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/CADw4SdREZTpyF84ZHkA%3Dp%2BdMZ-V%3D0drdyTp_XVFPc=
WqUF%3Ds0cA%40mail.gmail.com.

--001a11408742936e0e0554396de7
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Thu, Jul 13, 2017 at 8:21 PM, Arthur O&#39;Dwyer <span dir=3D"ltr">&=
lt;<a href=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.=
odwyer@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote"=
 style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:=
solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"=
><div><div class=3D"gmail-h5">On Wednesday, July 12, 2017 at 6:43:11 PM UTC=
-7, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px=
 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-co=
lor:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">On Wednesday, July =
12, 2017 at 7:47:05 PM UTC-4, Arthur O&#39;Dwyer wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;borde=
r-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><di=
v dir=3D"ltr">On Wednesday, July 12, 2017 at 2:53:19 AM UTC-7, <a>d...@soun=
dradix.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px =
0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-col=
or:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">Hi,<div><br></div><d=
iv>Would anyone be interested in adding std::shift to &lt;algorithm&gt;?=C2=
=A0</div><div><br></div><div>It would be similar to both:</div><div>- std::=
rotate, but without moving the head elements back to the tail. This would a=
llow a more efficient implementation and clearer semantics in case rotation=
 is not needed as well as correctness in case rotation is undesired.</div><=
div>- &lt;algorithm&gt;&#39;s std::move/std::move_backward (depending on th=
e shift direction).</div><div><br></div><div>std::shift should probably acc=
ommodate both left and right shifts by one of:</div><div>- giving it either=
 begin() and end(), or rbegin() and rend(), similar to how std::rotate work=
s for both left and right rotations. The advantage is compactness of the im=
plementation.</div><div>- allowing the shift count parameter to be either p=
ositive or negative. The advantage is compactness, though it might not be c=
lear which direction is which - to be consistent with rotate, positive inte=
gers should shift to the left.<br></div><div><div>- having std::shift_right=
 and std::shift_left functions. The advantage is clarity when calling the m=
ethods, although the same argument could be made for having separate std::r=
otate_left and std::rotate_right instead of std::rotate, which we don&#39;t=
 have.</div></div></div></blockquote><div><br></div><div>std::rotate is act=
ually just a rotation; it doesn&#39;t need &quot;left&quot; or &quot;right&=
quot; qualification because they&#39;re 100% equivalent. Consider a classro=
om globe with London in front, facing you. Now &quot;rotate&quot; the globe=
 until Beijing is in front. It doesn&#39;t matter if you rotate left or rot=
ate right; the outcome is exactly the same either way.</div><div>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;borde=
r-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204)=
;padding-left:1ex"><div dir=3D"ltr"><div>Here&#39;s a sample implementation=
 of a shift to the right direction:<br></div><br><div style=3D"background-c=
olor:rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:break-wor=
d"><code><div><span style=3D"color:rgb(0,0,136)">template</span><span style=
=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,136)">cla=
ss</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(=
102,0,102)">BidirIt</span><span style=3D"color:rgb(102,102,0)">&gt;</span><=
span style=3D"color:rgb(0,0,0)"> <br></span><span style=3D"color:rgb(0,0,13=
6)">void</span><span style=3D"color:rgb(0,0,0)"> shift_right</span><span st=
yle=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,0,102)">B=
idirIt</span><span style=3D"color:rgb(0,0,0)"> first</span><span style=3D"c=
olor:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> </span><span=
 style=3D"color:rgb(102,0,102)">BidirIt</span><span style=3D"color:rgb(0,0,=
0)"> </span><span style=3D"color:rgb(0,0,136)">last</span><span style=3D"co=
lor:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> </span><span =
style=3D"color:rgb(0,0,136)">unsigned</span><span style=3D"color:rgb(0,0,0)=
"> </span><span style=3D"color:rgb(0,0,136)">int</span><span style=3D"color=
:rgb(0,0,0)"> n </span><span style=3D"color:rgb(102,102,0)">=3D</span><span=
 style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,102,102)">1<=
/span><span style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb=
(0,0,0)"> <br></span><span style=3D"color:rgb(102,102,0)">{</span><span sty=
le=3D"color:rgb(0,0,0)"> <br>=C2=A0 =C2=A0 std</span><span style=3D"color:r=
gb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">move_backward</spa=
n><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0=
,0)">first</span><span style=3D"color:rgb(102,102,0)">,</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">last</span=
><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,=
0)">-</span><span style=3D"color:rgb(0,0,0)"> n</span><span style=3D"color:=
rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> </span><span styl=
e=3D"color:rgb(0,0,136)">last</span><span style=3D"color:rgb(102,102,0)">);=
</span><span style=3D"color:rgb(0,0,0)"> <br></span><span style=3D"color:rg=
b(102,102,0)">}</span><span style=3D"color:rgb(0,0,0)"><br></span></div></c=
ode></div><div><br></div><div>This demonstrates that while std::shift is im=
plementable with std::move/std::move_backward,</div><div>1) It isn&#39;t im=
mediately clear from the code (at least to my eyes) that this is a shift ri=
ght, unless you are intimately familiar with std::move_backward.</div><div>=
2) Different calls, either to std::move or to std::move_backward, are requi=
red, depending on the shift direction.</div></div></blockquote><div><br></d=
iv><div>If you&#39;re shifting the whole container&#39;s contents, you coul=
d use either of these:</div><div>=C2=A0 =C2=A0 std::move(ctr.rbegin() + n, =
ctr.rend(), ctr.rbegin());</div><div>=C2=A0 =C2=A0 std::move_backward(ctr.b=
egin()<wbr>, ctr.end() - n, ctr.end())?</div><div>I don&#39;t currently see=
 the use-case for this &quot;shift just a piece of a container&quot; algori=
thm, I mean as distinct from std::move and std::move_backward which already=
 exist. Do you have a use-case?</div></div></blockquote><div><br>The use-ca=
se would be anytime you&#39;d want to use the code you just wrote. When you=
 have a range and N, and you want to do a shift N units in that direction.<=
br><br>The point of having it is one of clarification and user expectations=
.. Yes, you can use `move` and `move_backward` to accomplish a shift. But co=
nsider the two function calls:<br><br><div style=3D"background-color:rgb(25=
0,250,250);border:1px solid rgb(187,187,187)"><code><div><span style=3D"col=
or:rgb(136,0,0)">//A</span><span style=3D"color:rgb(0,0,0)"><br>std</span><=
span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0=
)">shift</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"=
color:rgb(0,0,0)">rng</span><span style=3D"color:rgb(102,102,0)">.</span><s=
pan style=3D"color:rgb(0,0,136)">begin</span><span style=3D"color:rgb(102,1=
02,0)">(),</span><span style=3D"color:rgb(0,0,0)"> rng</span><span style=3D=
"color:rgb(102,102,0)">.</span><span style=3D"color:rgb(0,0,136)">end</span=
><span style=3D"color:rgb(102,102,0)">(),</span><span style=3D"color:rgb(0,=
0,0)"> N</span><span style=3D"color:rgb(102,102,0)">);</span><span style=3D=
"color:rgb(0,0,0)"><br><br></span><span style=3D"color:rgb(136,0,0)">//B</s=
pan><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,=
0,136)">auto</span><span style=3D"color:rgb(0,0,0)"> rrng </span><span styl=
e=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> std<=
/span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rg=
b(0,0,0)">make_reverse_range</span><span style=3D"color:rgb(102,102,0)">(</=
span><span style=3D"color:rgb(0,0,0)">rng</span><span style=3D"color:rgb(10=
2,102,0)">);</span><span style=3D"color:rgb(0,0,0)"><br>std</span><span sty=
le=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">move<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb=
(0,0,0)">rrng</span><span style=3D"color:rgb(102,102,0)">.</span><span styl=
e=3D"color:rgb(0,0,136)">begin</span><span style=3D"color:rgb(102,102,0)">(=
)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(1=
02,102,0)">+</span><span style=3D"color:rgb(0,0,0)"> N</span><span style=3D=
"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> rrng</span=
><span style=3D"color:rgb(102,102,0)">.</span><span style=3D"color:rgb(0,0,=
136)">end</span><span style=3D"color:rgb(102,102,0)">(),</span><span style=
=3D"color:rgb(0,0,0)"> rrng</span><span style=3D"color:rgb(102,102,0)">.</s=
pan><span style=3D"color:rgb(0,0,136)">begin</span><span style=3D"color:rgb=
(102,102,0)">());</span></div></code></div><br>A and B both do the same thi=
ng. But it&#39;s a <i>lot easier</i> to figure out what the code is actuall=
y accomplishing from looking at A than B.<br></div></div></blockquote><div>=
<br></div></div></div><div>Do you have a use-case for either of these?</div=
><div>I recall your admonition cross-thread that generally in the STL we *d=
on&#39;t* want to operate on containers but rather on ranges (or iterator-p=
airs); so if I had a range that I wanted to &quot;shift&quot;, I would firs=
t consider whether I could do something like</div><div><br></div><div>=C2=
=A0 =C2=A0 // OLD: shift_in_place(range, n); operate_on(range.begin(), rang=
e.end());</div><div>=C2=A0 =C2=A0 // NEW: operate_on(range.begin() + n, ran=
ge.end());</div><div><br></div><div>That is, instead of moving the actual d=
ata, which might be slow, I&#39;d move one or the other &quot;endpoint&quot=
; while leaving the data in place.</div><div>In his reply, Dan Raviv mentio=
ned that this is exactly the kind of thing that a circular buffer does, and=
 he&#39;s right (see proposal P0059).</div><span class=3D"gmail-"><div><br>=
</div></span></div></blockquote><div><span style=3D"font-size:12.8000001907=
34863px">I also wrote that sometimes the circular buffer is less desirable =
than just shifting the data.</span></div><div><span style=3D"font-size:12.8=
00000190734863px"><br></span></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;=
border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><span=
 class=3D"gmail-"><div></div><div><br></div><div><br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;b=
order-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"=
><div dir=3D"ltr"><div>B gets even more obtuse confusing in a range-based w=
orld:<br><br><div style=3D"background-color:rgb(250,250,250);border:1px sol=
id rgb(187,187,187)"><code><div><span style=3D"color:rgb(136,0,0)">//A</spa=
n><span style=3D"color:rgb(0,0,0)"><br>std</span><span style=3D"color:rgb(1=
02,102,0)">::</span><span style=3D"color:rgb(0,0,0)">shift</span><span styl=
e=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">rng</sp=
an><span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,=
0,0)"> N</span><span style=3D"color:rgb(102,102,0)">);</span><span style=3D=
"color:rgb(0,0,0)"><br><br></span><span style=3D"color:rgb(136,0,0)">//B</s=
pan><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,=
0,136)">auto</span><span style=3D"color:rgb(0,0,0)"> rrng </span><span styl=
e=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> std<=
/span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rg=
b(0,0,0)">make_reverse_range</span><span style=3D"color:rgb(102,102,0)">(</=
span><span style=3D"color:rgb(0,0,0)">rng</span><span style=3D"color:rgb(10=
2,102,0)">);</span><span style=3D"color:rgb(0,0,0)"><br>std</span><span sty=
le=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">move<=
/span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb=
(0,0,0)">std</span><span style=3D"color:rgb(102,102,0)">::</span><span styl=
e=3D"color:rgb(0,0,0)">make_range</span><span style=3D"color:rgb(102,102,0)=
">(</span><span style=3D"color:rgb(0,0,0)">rrng</span><span style=3D"color:=
rgb(102,102,0)"><wbr>.</span><span style=3D"color:rgb(0,0,136)">begin</span=
><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,=
0)">+</span><span style=3D"color:rgb(0,0,0)"> N</span><span style=3D"color:=
rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> rrng</span><span =
style=3D"color:rgb(102,102,0)">.</span><span style=3D"color:rgb(0,0,136)">e=
nd</span><span style=3D"color:rgb(102,102,0)">()),</span><span style=3D"col=
or:rgb(0,0,0)"> rrng</span><span style=3D"color:rgb(102,102,0)">.</span><sp=
an style=3D"color:rgb(0,0,136)">begin</span><span style=3D"color:rgb(102,10=
2,0)">());</span></div></code></div></div></div></blockquote><div><br></div=
></span><div>In a range-based world, I would write this as</div><div><br></=
div><div>=C2=A0 =C2=A0 auto output =3D input | rng::drop(n);</div><div><br>=
</div><div>for a &quot;left-shift&quot;, or... okay, the &quot;right-shift&=
quot; version is messy, at least in my version, because it involves concate=
nating ranges one of which needs to be created out of whole cloth, with n o=
bjects, each of which is in a &quot;valid but unspecified&quot; state. =C2=
=A0(I&#39;d bet <i>money</i> you can&#39;t give me a use-case for <i>that</=
i> one.)</div><div><br></div><div>I&#39;d still like to see a use-case for =
O(n) &quot;shifting&quot; a sequence of elements in-place (as opposed to us=
ing one of these range-based approaches, or using a circular buffer, or &qu=
ot;shifting the endpoints&quot;).=C2=A0 I agree that sometimes you do want =
to copy/move the second part of a sequence over the first part, but I would=
 always express that in terms of &quot;I&#39;m std::copy&#39;ing / std::mov=
e&#39;ing data.&quot; Expressing it as a &quot;shift&quot; doesn&#39;t feel=
 natural to me in any of the (extremely rare) use-cases I&#39;ve thought of=
.. Do you have a use-case?</div><div><br></div></div></blockquote><div>Expre=
ssing a shift (either forward or backward) seems more natural to me then co=
pying or moving, which are generic operations, but require more effort on t=
he reader&#39;s part in case they are used for a simple shift. And as I men=
tioned, a common use case in DSP for shifting is time series analysis.</div=
><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:=
rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div></div><div>=E2=80=
=93Arthur</div></div><span class=3D"gmail-">

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/99d55051-ad56-4386-8a0f-9d7627b63106%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/99d5=
5051-ad56-4386-<wbr>8a0f-9d7627b63106%40isocpp.org</a><wbr>.<br>
</blockquote></div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADw4SdREZTpyF84ZHkA%3Dp%2BdMZ-V%3D0d=
rdyTp_XVFPcWqUF%3Ds0cA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADw4SdRE=
ZTpyF84ZHkA%3Dp%2BdMZ-V%3D0drdyTp_XVFPcWqUF%3Ds0cA%40mail.gmail.com</a>.<br=
 />

--001a11408742936e0e0554396de7--

.
