220 30022 <2f450f27-18b4-440b-8f54-9fbc1e2598f9@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: join/split for string & string_view
Date: Sun, 25 Dec 2016 09:27:47 -0800 (PST)
Lines: 408
Approved: news@gmane.org
Message-ID: <2f450f27-18b4-440b-8f54-9fbc1e2598f9@isocpp.org>
References: <f609c0d3-c9ba-4a64-a99f-c2e64091b4e2@isocpp.org>
 <d8544b44-9ed4-403d-a980-6dda516933f6@isocpp.org> <172d08f0-a3da-4b9e-bfdd-985fb1f527c8@isocpp.org>
 <CAFdMc-07FWpV07b3WSz0U=uDNHXM19xgBTH=Cpt=Kvty4886FQ@mail.gmail.com>
 <CAFdMc-1sKQUs_ziOQwEZsOTLRDLrhjVSzLK_Jku27-XwkscQ+g@mail.gmail.com> <CAFdMc-2Fgm3A2JjbERdCeFqDDFFTHhWFLPEr6Jw4uPp2dw1Pbg@mail.gmail.com>
 <CAFdMc-3RaU+gW0EnBPtSDsLVcxxBXmzxgrtJn_FtdWcubxVJeg@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_644_1556758899.1482686867680"
X-Trace: blaine.gmane.org 1482686873 24876 195.159.176.226 (25 Dec 2016 17:27:53 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Sun, 25 Dec 2016 17:27:53 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBFEDQDBQKGQEP5TGFLA@isocpp.org Sun Dec 25 18:27:47 2016
Return-path: <std-proposals+bncBCEKFTV6ZUMBBFEDQDBQKGQEP5TGFLA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yb0-f197.google.com ([209.85.213.197])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBFEDQDBQKGQEP5TGFLA@isocpp.org>)
	id 1cLCaG-0005YA-Sc
	for gclcip-std-proposals@m.gmane.org; Sun, 25 Dec 2016 18:27:45 +0100
Original-Received: by mail-yb0-f197.google.com with SMTP id n141sf37561965ybf.0
        for <gclcip-std-proposals@m.gmane.org>; Sun, 25 Dec 2016 09:27:49 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=xfem6KHkXdpCrd4iyyN7JosbUGX6/Ja3Bng2nBo2pH0=;
        b=if8AEu96PCJbMaJvC267vwGO+qucitH8tZ0q6nKxPGJMPmpXmjKU0RvmBnbFLrxa9N
         1hJtM6n16elC1eg4QuvcAN1xNT7jhduOMr3igkfGZ98Aw1nfz7JYzCU5Kizib/nfm+6S
         rWM8ROJRTaSa916/9hV7XjlfCoOYEoKU7JdnsTAKPmbDEfXKwjApWGyNqfjwKaPP5AnS
         PneAG9vFGXhTsosESetBeMdwcNbCxWLjxnKXrggsU6FdQj1usqCJqHYS05kHGRgN1UVM
         0b9epvAcVF9ZZITSVkHXQ1AsSbb7nwncLTCvkLsXq1oa5An/OQPmUot+eC3QZIMBcADV
         IrKw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=xfem6KHkXdpCrd4iyyN7JosbUGX6/Ja3Bng2nBo2pH0=;
        b=fzcFeQEmRp8r8JTvTJjmmqxRaUW/YcZIpZuRtYotzC+da5F2c4JSCOL8wc5bgeaTtA
         hBOM/+1QGkY3I+tkEmgOPqDca4iMKpntXGnPtf0Bv7CvSG6a6hbTAIbWZzWNEd7iQJEi
         twXl2Jya6+pwxUATIBeNGK9Q+HCuRkhI0VfwD7miKs0eaVWuUyPd5m+zshD9T1RP7r1d
         h0CKcdyx+6FV117WjA2fRGwKHRXtikTFpX05mqTc1AZQnOC1mO7ZG552vE1Um1DbJ+tI
         VxN6IiuuKEqEYhWgjPwvD5J0JIDPYk557eJbBxhh+s2rqPBLZw4huQBWYiBiOzM4T34t
         GkYQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=xfem6KHkXdpCrd4iyyN7JosbUGX6/Ja3Bng2nBo2pH0=;
        b=JMs/Oob9ZK+MaIoRkxy4mFm3yI7KFC8g/dt4oRaxwJgDWcOB6H1B7wFdFyhPmu48SZ
         qn1TaWRInr1rtBxF/RSB7VCOxuWSpqkgvVWXkjrl19lx5HPR0MnSJ6WACFAde7D411N4
         kuw22WJ4yyMbmlk8tzLPTGRb4uBo1H05zxiCinhtIcNwYfXiCHOsV27p4Kqy7VFVymWr
         56v+09jo6o+NXuyiOVNnRRMhOZyJ3SwhO7hnTneqjS8Si2QAqGJseOPAVLSvdwttuhze
         m+KNzgZ5PRZDvE9T4YR7U3fnxY+s319OLRHPJWRDpq+EieliCuLN+/AO1TYw34tUkGHa
         yLSA==
X-Gm-Message-State: AIkVDXI3Twtxw9nhzaOsEoHZqvlo4aqyxKA9LyyF60UjjTcKaSKIAbBid47UMbFaO0m02A==
X-Received: by 10.129.37.11 with SMTP id l11mr6421768ywl.136.1482686869236;
        Sun, 25 Dec 2016 09:27:49 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.43.168 with SMTP id u37ls19477873ota.29.gmail; Sun, 25 Dec
 2016 09:27:48 -0800 (PST)
X-Received: by 10.157.17.3 with SMTP id g3mr1474546ote.8.1482686868458;
        Sun, 25 Dec 2016 09:27:48 -0800 (PST)
In-Reply-To: <CAFdMc-3RaU+gW0EnBPtSDsLVcxxBXmzxgrtJn_FtdWcubxVJeg@mail.gmail.com>
X-Original-Sender: jmckesson@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:30022
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/30022>

------=_Part_644_1556758899.1482686867680
Content-Type: multipart/alternative; 
	boundary="----=_Part_645_1330595686.1482686867681"

------=_Part_645_1330595686.1482686867681
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Sunday, December 25, 2016 at 11:25:39 AM UTC-5, dgutson wrote:
>
> Sorry for the spam, last email of my burst. I'm too drunk due to Christma=
s=20
> celebrations.
> My amendment below:
>
> On Sun, Dec 25, 2016 at 1:20 PM, dgutson . <daniel...@gmail.com=20
> <javascript:>> wrote:
>
>> s/allocators/iterators/
>>
>> El 25/12/2016 13:20, "dgutson ." <daniel...@gmail.com <javascript:>>=20
>> escribi=C3=B3:
>>
>>>
>>>
>>> El 25/12/2016 13:17, "dgutson ." <daniel...@gmail.com <javascript:>>=20
>>> escribi=C3=B3:
>>>
>>>
>>>
>>> El 25/12/2016 12:41, "Nicol Bolas" <jmck...@gmail.com <javascript:>>=20
>>> escribi=C3=B3:
>>>
>>> On Sunday, December 25, 2016 at 5:32:44 AM UTC-5, lnal...@gmail.com=20
>>> wrote:
>>>>
>>>> Hello,
>>>>
>>>>
>>>> Most of modern language (D, Python, Java, C#, Go, Rust) got a split=20
>>>> method on their string type, so I think it really make sense to have=
=20
>>>> something similar in C++.
>>>>
>>>
>>> All of those languages also only have a single string type. C++ has=20
>>> *hundreds*. Even the *standard library* has 2, and that doens't even=20
>>> count `const char*`.
>>>
>>> Having a `split` function that can *only* be used with the standard=20
>>> library string types is pathetic. Especially when it could be made to b=
e=20
>>> used with any string type (that provides a conversion to `string_view`)=
=20
>>> with ease.
>>>
>>> If you want to suggest that `basic_string` and `string_view` should hav=
e=20
>>> member versions that call the non-member algorithms, fine. But the=20
>>> non-member function is where the actual work happens.
>>> =20
>>>
>>>> All of them returns a 'vector' and I think is the main waited result.
>>>>
>>>
>>> No.
>>>
>>> While we should not be ignorant of what other languages are doing, we=
=20
>>> also should not pretend that the design of other languages is a priori=
=20
>>> correct for C++. We should do what is best for C++.
>>>
>>> And one principle of C++ is that we do not make people pay for features=
=20
>>> they don't need to use. Forcing the return of a `vector` makes people p=
ay=20
>>> for memory allocations that they may not use.
>>>
>>> I think it should not be required to mastering all subtilities of the=
=20
>>>> STL to do something a simple as that.
>>>>
>>>
>>> Master the subtleties of what? Of using a range? That should be an earl=
y=20
>>> lesson for C++ programmers; it's hardly deep metaprogramming magic.
>>>
>>> If you're going to be able to work in a language, you *need* to know=20
>>> its idioms. And ranges are very important idioms in C++. We shouldn't c=
ater=20
>>> to the demographic of people who learn just the syntax of a language an=
d=20
>>> then pretend that they know it.
>>>
>>> I think it should be possible to write :
>>>> auto MyResult=3D "my,csv,line"s.split(",");
>>>> myvar=3DMyResult[1];=20
>>>> for(auto sv : MyResult)=20
>>>>
>>>>
>>> Here is what that code would look like under the guidelines I (and=20
>>> others) outlined previously:
>>>
>>> vector MyResult(split("my,csv,line", ","));
>>> myvar =3D MyResult[1];
>>> for(auto sv : MyResult)
>>>
>>> See how simple that is? This only allocates memory in `vector`'s=20
>>> constructor (so you're not needlessly allocating a `basic_string`, just=
 for=20
>>> a string literal).
>>>
>>> Plus, if you just want the iteration, without the need for random acces=
s:
>>>
>>> for(auto sv : split("my,csv,line", ","))
>>>
>>> This performs *zero* memory allocations. Why *shouldn't* this be the=20
>>> default? In C++, the default ought to be fast, where possible.
>>>
>>>
>>> I think there should also be a callback-oriented version by providing a=
=20
>>> callable template argument (e.g. lambda, std::function, function ptr, e=
tc)=20
>>> which requires no memory allocation.
>>>
>>>
We don't need multiple versions. We can get the benefits of all of these=20
variants with just the range version. It's all about how you choose to=20
"store" the range. If you want no memory allocations, use `auto`. If you=20
want to allocate an array of `string_views`, use `vector<string_view>` or=
=20
just `vector`. If the string being split is temporary and you want to=20
allocate an array of actual strings, then use `vector<string>`.

If you want a callback to be called for each one, use for_each:

std::for_each(split(...), callback);

The performance characteristics of this should be more-or-less equivalent=
=20
to the performance characteristics of the callback-oriented version you=20
want.

We don't need a dozen different split functions; we can build all of the=20
rest manually and easily from just the lowest level one.


>>> BTW, this should work with any container that provides allocators,=20
>>> containing any type equal-comparable:
>>>
>>> vector<int> v;
>>> split(v, 1, [](int x){});
>>>
>>
>
> vector <int> v;
> split(v, 1, [ ] (const vector<int>& subvector) { });
>
> You got the idea, someone more sobre surely can write this better :)
>

The reason to limit `split` to strings specifically (and by "string", I=20
mean "contiguous range of characters") is because that restriction allows=
=20
us to use a specific concrete type for the resulting range's value_type:=20
`string_view`. Users are thus able to use a *specific* lingua franca type=
=20
that gives them reasonable safety and tools without making using the string=
=20
difficult. You can do things like equality test with literals and so forth,=
=20
which you can't do with an arbitrary iterator range type.

It also allows us to have the function take a `const char*` NUL-terminated=
=20
string. Plus, it allows us to implement that suggestion I made earlier,=20
where if you provide an rvalue for the input range to be split, then it=20
will move from that range into internal storage, so that it's much harder=
=20
to get pointers/references to temporaries. You wouldn't want to do that for=
=20
arbitrary containers of anything, but for strings, yes.

We should not over-generalize what we're making here. I'm sure there's some=
=20
need to split an arbitrary range into subranges based on an equality test=
=20
of a value. But that should be a different function from splitting a=20
string, based on quality-of-life for the resulting code.

--=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/2f450f27-18b4-440b-8f54-9fbc1e2598f9%40isocpp.or=
g.

------=_Part_645_1330595686.1482686867681
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, December 25, 2016 at 11:25:39 AM UTC-5,=
 dgutson wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><div>Sorry for the spam, last email of my burst. I&#39;m too drunk due to=
 Christmas celebrations.<br></div>My amendment below:<br><div><br><div clas=
s=3D"gmail_quote">On Sun, Dec 25, 2016 at 1:20 PM, dgutson . <span dir=3D"l=
tr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
zYq31ja1CAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&=
#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true=
;">daniel...@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"auto">s/allocators/iterators/</div><div><div><div><br><div =
class=3D"gmail_quote">El 25/12/2016 13:20, &quot;dgutson .&quot; &lt;<a hre=
f=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"zYq31ja1CAAJ" =
rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return tr=
ue;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">daniel...@g=
mail.com</a>&gt; escribi=C3=B3:<br type=3D"attribution"><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"auto"><div><br><div><br><div class=3D"gmail_quote=
">El 25/12/2016 13:17, &quot;dgutson .&quot; &lt;<a href=3D"javascript:" ta=
rget=3D"_blank" gdf-obfuscated-mailto=3D"zYq31ja1CAAJ" rel=3D"nofollow" onm=
ousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this=
..href=3D&#39;javascript:&#39;;return true;">daniel...@gmail.com</a>&gt; esc=
ribi=C3=B3:<br type=3D"attribution"><blockquote style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><div><div><b=
r><div><br><div class=3D"gmail_quote">El 25/12/2016 12:41, &quot;Nicol Bola=
s&quot; &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=
=3D"zYq31ja1CAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascri=
pt:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return =
true;">jmck...@gmail.com</a>&gt; escribi=C3=B3:<br type=3D"attribution"><bl=
ockquote style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div dir=3D"ltr"><div>On Sunday, December 25, 2016 at 5:32:44 AM UTC-=
5, <a>lnal...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><p>Hello,</p><p><br>Most of modern language (D, Python, J=
ava, C#, Go, Rust) got a split=20
method on their string type, so I think it really make sense to have someth=
ing=20
similar in C++.<br></p></div></blockquote></div><div><br>All of those langu=
ages also only have a single string type. C++ has <i>hundreds</i>. Even the=
 <i>standard library</i> has 2, and that doens&#39;t even count `const char=
*`.<br><br>Having a `split` function that can <i>only</i> be used with the =
standard library string types is pathetic. Especially when it could be made=
 to be used with any string type (that provides a conversion to `string_vie=
w`) with ease.<br><br>If you want to suggest that `basic_string` and `strin=
g_view` should have member versions that call the non-member algorithms, fi=
ne. But the non-member function is where the actual work happens.<br>=C2=A0=
</div><div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:=
0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><p>All =
of them returns a &#39;vector&#39; and I think is the main waited=20
result.</p></div></blockquote></div><div><br>No.<br><br>While we should not=
 be ignorant of what other languages are doing, we also should not pretend =
that the design of other languages is a priori correct for C++. We should d=
o what is best for C++.<br><br>And one principle of C++ is that we do not m=
ake people pay for features they don&#39;t need to use. Forcing the return =
of a `vector` makes people pay for memory allocations that they may not use=
..<br><br></div><div><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><p>I think it should=20
not be required to mastering all subtilities of the STL to do something a s=
imple=20
as that.</p></div></blockquote></div><div><br>Master the subtleties of what=
? Of using a range? That should be an early lesson for C++ programmers; it&=
#39;s hardly deep metaprogramming magic.<br><br>If you&#39;re going to be a=
ble to work in a language, you <i>need</i> to know its idioms. And ranges a=
re very important idioms in C++. We shouldn&#39;t cater to the demographic =
of people who learn just the syntax of a language and then pretend that the=
y know it.<br><br></div><div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr">
<p>I think it should be possible to write :</p>
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,18=
7);border-style:solid;border-width:1px;word-wrap:break-word"><code><div><sp=
an style=3D"color:#008">auto</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#606">MyResult</span><span style=3D"color:#660">=3D</span><=
span style=3D"color:#000"> </span><span style=3D"color:#080">&quot;my,csv,l=
ine&quot;</span><span style=3D"color:#000">s</span><span style=3D"color:#66=
0">.</span><span style=3D"color:#000">split</span><span style=3D"color:#660=
">(</span><span style=3D"color:#080">&quot;,&quot;</span><span style=3D"col=
or:#660">);</span><span style=3D"color:#000"><br>myvar</span><span style=3D=
"color:#660">=3D</span><span style=3D"color:#606">MyResult</span><span styl=
e=3D"color:#660">[</span><span style=3D"color:#066">1</span><span style=3D"=
color:#660">];</span><span style=3D"color:#000"> <br></span><span style=3D"=
color:#008">for</span><span style=3D"color:#660">(</span><span style=3D"col=
or:#008">auto</span><span style=3D"color:#000"> sv </span><span style=3D"co=
lor:#660">:</span><span style=3D"color:#000"> </span><span style=3D"color:#=
606">MyResult</span><span style=3D"color:#660">)</span><span style=3D"color=
:#000"> <br></span></div></code></div><p></p></div></blockquote></div><div>=
<br>Here is what that code would look like under the guidelines I (and othe=
rs) outlined previously:<br><br><div style=3D"background-color:rgb(250,250,=
250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><co=
de><div><span style=3D"color:#000">vector </span><span style=3D"color:#606"=
>MyResult</span><span style=3D"color:#660">(</span><span style=3D"color:#00=
0">split</span><span style=3D"color:#660">(</span><span style=3D"color:#080=
">&quot;my,csv,line&quot;</span><span style=3D"color:#660">,</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#080">&quot;,&quot;</span><=
span style=3D"color:#660">));</span><span style=3D"color:#000"><br>myvar </=
span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#606">MyResult</span><span style=3D"color:#660">[</s=
pan><span style=3D"color:#066">1</span><span style=3D"color:#660">];</span>=
<span style=3D"color:#000"><br></span><span style=3D"color:#008">for</span>=
<span style=3D"color:#660">(</span><span style=3D"color:#008">auto</span><s=
pan style=3D"color:#000"> sv </span><span style=3D"color:#660">:</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#606">MyResult</span><s=
pan style=3D"color:#660">)</span></div></code></div><br>See how simple that=
 is? This only allocates memory in `vector`&#39;s constructor (so you&#39;r=
e not needlessly allocating a `basic_string`, just for a string literal).<b=
r><br>Plus, if you just want the iteration, without the need for random acc=
ess:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:rg=
b(187,187,187);border-style:solid;border-width:1px"><code><div><span style=
=3D"color:#008">for</span><span style=3D"color:#660">(</span><span style=3D=
"color:#008">auto</span><span style=3D"color:#000"> sv </span><span style=
=3D"color:#660">:</span><span style=3D"color:#000"> split</span><span style=
=3D"color:#660">(</span><span style=3D"color:#080">&quot;my,csv,line&quot;<=
/span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span=
><span style=3D"color:#080">&quot;,&quot;</span><span style=3D"color:#660">=
))</span></div></code></div><br>This performs <i>zero</i> memory allocation=
s. Why <i>shouldn&#39;t</i> this be the default? In C++, the default ought =
to be fast, where possible.<br></div></div></blockquote></div></div></div><=
div dir=3D"auto"><br></div></div><div dir=3D"auto">I think there should als=
o be a callback-oriented version by providing a callable template argument =
(e.g. lambda, std::function, function ptr, etc) which requires no memory al=
location.</div></div></blockquote></div></div></div></div></blockquote></di=
v></div></div></div></blockquote></div></div></div></blockquote><div><br>We=
 don&#39;t need multiple versions. We can get the benefits of all of these =
variants with just the range version. It&#39;s all about how you choose to =
&quot;store&quot; the range. If you want no memory allocations, use `auto`.=
 If you want to allocate an array of `string_views`, use `vector&lt;string_=
view&gt;` or just `vector`. If the string being split is temporary and you =
want to allocate an array of actual strings, then use `vector&lt;string&gt;=
`.<br><br>If you want a callback to be called for each one, use for_each:<b=
r><br><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb=
(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: bre=
ak-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"s=
ubprettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">st=
d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">for_each</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">split</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(...),</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> callback</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">);</span></div></code></div><br>The pe=
rformance characteristics of this should be more-or-less equivalent to the =
performance characteristics of the callback-oriented version you want.<br><=
br>We don&#39;t need a dozen different split functions; we can build all of=
 the rest manually and easily from just the lowest level one.<br><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div cla=
ss=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 =
..8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><div dir=
=3D"auto"></div><div dir=3D"auto"><br></div><div dir=3D"auto">BTW, this sho=
uld work with any container that provides allocators, containing any type e=
qual-comparable:</div><div dir=3D"auto"><br></div><div dir=3D"auto">vector&=
lt;int&gt; v;</div><div dir=3D"auto">split(v, 1, [](int x){});</div></div><=
/blockquote></div></div></div></div></blockquote><div><br><br></div><div>ve=
ctor &lt;int&gt; v;<br></div><div>split(v, 1, [ ] (const vector&lt;int&gt;&=
amp; subvector) { });<br><br></div><div>You got the idea, someone more sobr=
e surely can write this better :)<br></div></div></div></div></blockquote><=
div><br>The reason to limit `split` to strings specifically (and by &quot;s=
tring&quot;, I mean &quot;contiguous range of characters&quot;) is because =
that restriction allows us to use a specific concrete type for the resultin=
g range&#39;s value_type: `string_view`. Users are thus able to use a <i>sp=
ecific</i> lingua franca type that gives them reasonable safety and tools w=
ithout making using the string difficult. You can do things like equality t=
est with literals and so forth, which you can&#39;t do with an arbitrary it=
erator range type.<br><br>It also allows us to have the function take a `co=
nst char*` NUL-terminated string. Plus, it allows us to implement that sugg=
estion I made earlier, where if you provide an rvalue for the input range t=
o be split, then it will move from that range into internal storage, so tha=
t it&#39;s much harder to get pointers/references to temporaries. You would=
n&#39;t want to do that for arbitrary containers of anything, but for strin=
gs, yes.<br><br>We should not over-generalize what we&#39;re making here. I=
&#39;m sure there&#39;s some need to split an arbitrary range into subrange=
s based on an equality test of a value. But that should be a different func=
tion from splitting a string, based on quality-of-life for the resulting co=
de.<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/2f450f27-18b4-440b-8f54-9fbc1e2598f9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2f450f27-18b4-440b-8f54-9fbc1e2598f9=
%40isocpp.org</a>.<br />

------=_Part_645_1330595686.1482686867681--

------=_Part_644_1556758899.1482686867680--

.
