Topic: Multiple-Get Method for Containers


Author: wargo.john25@gmail.com
Date: Wed, 16 May 2018 17:44:58 -0700 (PDT)
Raw View
------=_Part_1926_772052566.1526517898731
Content-Type: multipart/alternative;
 boundary="----=_Part_1927_734465151.1526517898732"

------=_Part_1927_734465151.1526517898732
Content-Type: text/plain; charset="UTF-8"

I've been sharpening my template machinery lately, and with the recent
advent of structured binding declarations, it occurred to me that an access
method for containers that was capable of returning multiple values as a
tuple could be really useful.

Given that I'm not certain on my phraseology, I think source code would be
ideal, so attached is an example of a string splitting function where the
individual results can be saved off as a structured binding without the use
of any temporary variables.

A few points of discussion (in addition to anything else you guys come up
with)

   - I did it this time by returning a tuple of values instead of a tuple
   of references, so that they would not be dangling at the end of the split
   function. For more complex types in certain circumstances, there could be
   reason to have a reference version that returns the tuple of references (or
   maybe even a move version that moves it's accessed members out with)
   - I used 'get' as the method name, because it almost lends itself to an
   overload of the tuple version of get, where you could get multiple values
   out of a tuple with the same syntax.
      - Vectors don't have a tuple-like get method (for good reason), and
      they could definitely benefit from this, so maybe leaving it as a member
      function is the best idea
   - I'm sure with a little playing there's a way to get the bracket
   operators to take a tuple/init_list of indices, at which point `auto const&
   [first, last] = split(...)[{0,1}]` would work, *might* be more natural
      - The existing `.at()` function could *easily* be adopted to do this
      too, but it has performance drawbacks, so I almost never use it in
      production code...

All in all, I think this fits nicely with the recent addition of structured
binding declarations, so I wanted to throw it out here as a possible
addition to the STL.
I don't see it possibly conflicting with anything that's already
implemented, and it's really easy to implement itself, but then again maybe
it's not as cool as I thought, or maybe I missed something.

Thoughts?

--
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/968e6011-f73e-4cc0-9b5e-7b39fbfcf929%40isocpp.org.

------=_Part_1927_734465151.1526517898732
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I&#39;ve been sharpening my template machinery lately, and=
 with the recent advent of structured binding declarations, it occurred to =
me that an access method for containers that was capable of returning multi=
ple values as a tuple could be really useful.<div><br></div><div>Given that=
 I&#39;m not certain on my phraseology, I think source code would be ideal,=
 so attached is an example of a string splitting function where the individ=
ual results can be saved off as a structured binding without the use of any=
 temporary variables.</div><div><br></div><div>A few points of discussion (=
in addition to anything else you guys come up with)</div><div><ul><li><div>=
I did it this time by returning a tuple of values instead of a tuple of ref=
erences, so that they would not be dangling at the end of the split functio=
n. For more complex types in certain circumstances, there could be reason t=
o have a reference version that returns the tuple of references (or maybe e=
ven a move version that moves it&#39;s accessed members out with)</div></li=
><li>I used &#39;get&#39; as the method name, because it almost lends itsel=
f to an overload of the tuple version of get, where you could get multiple =
values out of a tuple with the same syntax.</li><ul><li>Vectors don&#39;t h=
ave a tuple-like get method (for good reason), and they could definitely be=
nefit from this, so maybe leaving it as a member function is the best idea<=
/li></ul><li>I&#39;m sure with a little playing there&#39;s a way to get th=
e bracket operators to take a tuple/init_list of indices, at which point `a=
uto const&amp; [first, last] =3D split(...)[{0,1}]` would work, <i>might</i=
>=C2=A0be more natural</li><ul><li>The existing `.at()` function could <i>e=
asily</i>=C2=A0be adopted to do this too, but it has performance drawbacks,=
 so I almost never use it in production code...</li></ul></ul><div>All in a=
ll, I think this fits nicely with the recent addition of structured binding=
 declarations, so I wanted to throw it out here as a possible addition to t=
he STL.</div></div><div>I don&#39;t see it possibly conflicting with anythi=
ng that&#39;s already implemented, and it&#39;s really easy to implement it=
self, but then again maybe it&#39;s not as cool as I thought, or maybe I mi=
ssed something.</div><div><br></div><div>Thoughts?</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/968e6011-f73e-4cc0-9b5e-7b39fbfcf929%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/968e6011-f73e-4cc0-9b5e-7b39fbfcf929=
%40isocpp.org</a>.<br />

------=_Part_1927_734465151.1526517898732--

------=_Part_1926_772052566.1526517898731
Content-Type: text/x-c++src; charset=UTF-16LE; name=MultiGetVector.cpp
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=MultiGetVector.cpp
X-Attachment-Id: 99335f28-dea6-4886-b315-8a3058d3925e
Content-ID: <99335f28-dea6-4886-b315-8a3058d3925e>

//4jAGkAbgBjAGwAdQBkAGUAIAA8AHMAdAByAGkAbgBnAD4ADQAKACMAaQBuAGMAbAB1AGQAZQAg
ADwAdAB1AHAAbABlAD4ADQAKACMAaQBuAGMAbAB1AGQAZQAgADwAaQBvAHMAdAByAGUAYQBtAD4A
DQAKACMAaQBuAGMAbAB1AGQAZQAgADwAdgBlAGMAdABvAHIAPgANAAoADQAKAHQAZQBtAHAAbABh
AHQAZQA8AHQAeQBwAGUAbgBhAG0AZQAgAFQAPgANAAoAYwBsAGEAcwBzACAATQB1AGwAdABpAEcA
ZQB0AFYAZQBjAHQAbwByACAAOgAgAHAAdQBiAGwAaQBjACAAcwB0AGQAOgA6AHYAZQBjAHQAbwBy
ADwAVAA+AA0ACgB7AA0ACgBwAHUAYgBsAGkAYwA6AA0ACgAgACAALwAqACoAIABJAG4AaABlAHIA
aQB0ACAAQwBvAG4AcwB0AHIAdQBjAHQAbwByACAAKgAvAA0ACgAgACAAdQBzAGkAbgBnACAAcwB0
AGQAOgA6AHYAZQBjAHQAbwByADwAVAA+ADoAOgB2AGUAYwB0AG8AcgA7AA0ACgANAAoAIAAgAC8A
KgAqACAAUwB0AGEAbgBkAGEAcgBkACAARwBlAHQAIAAqAC8ADQAKACAAIABzAHQAZAA6ADoAdAB1
AHAAbABlADwAVAA+ACAAZwBlAHQAKABzAHQAZAA6ADoAcwBpAHoAZQBfAHQAIABpACkADQAKACAA
IAB7AA0ACgAgACAAIAAgAHIAZQB0AHUAcgBuACAAewAoACoAdABoAGkAcwApAFsAaQBdAH0AOwAN
AAoAIAAgAH0ADQAKAA0ACgAgACAALwAqACoAIABNAGEAZwBpAGMAYQBsACAARwBlAHQAIAAqAC8A
DQAKACAAIAB0AGUAbQBwAGwAYQB0AGUAPAB0AHkAcABlAG4AYQBtAGUALgAuAC4AIABJAG4AZABp
AGMAZQBzAD4ADQAKACAAIABhAHUAdABvACAAZwBlAHQAKABzAHQAZAA6ADoAcwBpAHoAZQBfAHQA
IABpACwAIABJAG4AZABpAGMAZQBzAC4ALgAuACAAaQBuAGQAaQBjAGUAcwApAA0ACgAgACAAewAN
AAoAIAAgACAAIAByAGUAdAB1AHIAbgAgAHMAdABkADoAOgB0AHUAcABsAGUAXwBjAGEAdAAoAGcA
ZQB0ACgAaQApACwAIABnAGUAdAAoAGkAbgBkAGkAYwBlAHMALgAuAC4AKQApADsADQAKACAAIAB9
AA0ACgB9ADsADQAKAA0ACgAvACoAKgANAAoAIAAqACAAQABwAGEAcgBhAG0AIABzAHQAcgAgACAA
IAAgACAAIAAgAFMAdAByAGkAbgBnACAAdABvACAAcwBwAGwAaQB0AA0ACgAgACoAIABAAHAAYQBy
AGEAbQAgAGQAZQBsAGkAbQBpAHQAIAAgACAAUwB0AHIAaQBuAGcAIAB0AG8AIABzAHAAbABpAHQA
IABvAG4ADQAKACAAKgAvAA0ACgBNAHUAbAB0AGkARwBlAHQAVgBlAGMAdABvAHIAPABzAHQAZAA6
ADoAcwB0AHIAaQBuAGcAPgAgAHMAcABsAGkAdAAoAHMAdABkADoAOgBzAHQAcgBpAG4AZwAgAGMA
bwBuAHMAdAAmACAAcwB0AHIALAAgAHMAdABkADoAOgBzAHQAcgBpAG4AZwAgAGMAbwBuAHMAdAAm
ACAAZABlAGwAaQBtAGkAdAApAA0ACgB7AA0ACgAgACAATQB1AGwAdABpAEcAZQB0AFYAZQBjAHQA
bwByADwAcwB0AGQAOgA6AHMAdAByAGkAbgBnAD4AIAByAGUAcwB1AGwAdAB7AHMAdAByAH0AOwAN
AAoADQAKACAAIABmAG8AcgAoAHMAdABkADoAOgBzAGkAegBlAF8AdAAgAHAAbwBzACAAPQAgAHIA
ZQBzAHUAbAB0AC4AYgBhAGMAawAoACkALgBmAGkAbgBkACgAZABlAGwAaQBtAGkAdAApADsADQAK
ACAAIAAgACAAIAAgAHAAbwBzACAAIQA9ACAAcwB0AGQAOgA6AHMAdAByAGkAbgBnADoAOgBuAHAA
bwBzADsADQAKACAAIAAgACAAIAAgAHAAbwBzACAAPQAgAHIAZQBzAHUAbAB0AC4AYgBhAGMAawAo
ACkALgBmAGkAbgBkACgAZABlAGwAaQBtAGkAdAApACkADQAKACAAIAB7AA0ACgAgACAAIAAgAHMA
dABkADoAOgBzAHQAcgBpAG4AZwAgAHQAZQBtAHAAIAA9ACAAcgBlAHMAdQBsAHQALgBiAGEAYwBr
ACgAKQAuAHMAdQBiAHMAdAByACgAcABvAHMAIAArACAAZABlAGwAaQBtAGkAdAAuAHMAaQB6AGUA
KAApACkAOwANAAoAIAAgACAAIAByAGUAcwB1AGwAdAAuAGIAYQBjAGsAKAApAC4AZQByAGEAcwBl
ACgAcABvAHMAKQA7AA0ACgAgACAAIAAgAHIAZQBzAHUAbAB0AC4AcAB1AHMAaABfAGIAYQBjAGsA
KAB0AGUAbQBwACkAOwANAAoAIAAgAH0ADQAKAA0ACgAgACAAcgBlAHQAdQByAG4AIAByAGUAcwB1
AGwAdAA7AA0ACgB9AA0ACgANAAoAaQBuAHQAIABtAGEAaQBuACgAKQANAAoAewANAAoAIAAgAGEA
dQB0AG8AIABjAG8AbgBzAHQAJgBbAGYAaQByAHMAdAAsACAAbABhAHMAdABdACAAPQAgAHMAcABs
AGkAdAAoACIASgBvAGgAbgAgAFMAbQBpAHQAaAAiACwAIAAiACAAIgApAC4AZwBlAHQAKAAwACwA
MQApADsADQAKACAAIABzAHQAZAA6ADoAYwBvAHUAdAAgADwAPAAgACIARgBpAHIAcwB0ACAATgBh
AG0AZQAgADoAIAAiACAAPAA8ACAAZgBpAHIAcwB0ACAAPAA8ACAAIgBcAG4AIgA7AA0ACgAgACAA
cwB0AGQAOgA6AGMAbwB1AHQAIAA8ADwAIAAiAEwAYQBzAHQAIABOAGEAbQBlACAAIAA6ACAAIgAg
ADwAPAAgAGwAYQBzAHQAIAA8ADwAIAAiAFwAbgAiADsADQAKACAAIABzAHQAZAA6ADoAYwBvAHUA
dAAgADwAPAAgAHMAdABkADoAOgBlAG4AZABsADsADQAKAH0ADQAKAA==
------=_Part_1926_772052566.1526517898731--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Thu, 17 May 2018 17:20:30 -0700 (PDT)
Raw View
------=_Part_7839_219147667.1526602830400
Content-Type: multipart/alternative;
 boundary="----=_Part_7840_710818855.1526602830401"

------=_Part_7840_710818855.1526602830401
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Wednesday, May 16, 2018 at 5:44:58 PM UTC-7, wargo....@gmail.com wrote:
>
> I've been sharpening my template machinery lately, and with the recent=20
> advent of structured binding declarations, it occurred to me that an acce=
ss=20
> method for containers that was capable of returning multiple values as a=
=20
> tuple could be really useful.
>
> Given that I'm not certain on my phraseology, I think source code would b=
e=20
> ideal, so attached is an example of a string splitting function where the=
=20
> individual results can be saved off as a structured binding without the u=
se=20
> of any temporary variables.
>
> A few points of discussion (in addition to anything else you guys come up=
=20
> with)
>
>    - I did it this time by returning a tuple of values instead of a tuple=
=20
>    of references, so that they would not be dangling at the end of the sp=
lit=20
>    function. For more complex types in certain circumstances, there could=
 be=20
>    reason to have a reference version that returns the tuple of reference=
s (or=20
>    maybe even a move version that moves it's accessed members out with)
>   =20
> This is the biggest "point of discussion" I see with what you've made. Yo=
u=20
write:

    auto const&[first, last] =3D split("John Smith", " ").get(0,1);


What this actually does is:
- Construct a vector<string> of all the substrings in the split
- Copy two of these substrings into a tuple<string, string>
- Bind `first` and `last` to the elements of this tuple

What we'd like it to do is *at least*:
- Construct a vector<string> of all the substrings in the split
- Copy two of these substrings into a tuple<string, string>
- Bind `first` and `last` to two of these substrings

with no extra copies. But if we try returning a tuple<string&, string&>, we=
=20
run into dangling-reference problems, as you noticed.
(And maybe we even want to go further and do something with lazy generators=
=20
so that we don't have to allocate that vector<string> to begin with.)
I think the idea as implemented here is too inefficient to be suitable for=
=20
the STL.

Orthogonally, I think the idea is not *useful* enough for the STL either,=
=20
but that's a less important and less objective point than the=20
efficiency/lifetime concern.


Also, just a nitpick on your metaprogramming:

  /** Magical Get */
  template<typename... Indices>
  auto get(std::size_t i, Indices... indices)
  {
    return std::tuple_cat(get(i), get(indices...));
  }


You could write simply


  /** Magical Get */
  template<typename... Indices>
  auto get(Indices... indices)
  {
    return std::make_tuple(get(indices)...);
  }


and it would have the same effect in all relevant respects, but without the=
=20
recursive template instantiations.


For prior art in the area of "take a container and produce a new view onto =
it by shuffling and/or subsetting its indices," you might want to take a lo=
ok at std::valarray's operator[] overloads.


=E2=80=93Arthur

--=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/67bd9d4b-cec0-4b20-95c5-1bfe201edc92%40isocpp.or=
g.

------=_Part_7840_710818855.1526602830401
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, May 16, 2018 at 5:44:58 PM UTC-7, wargo....@=
gmail.com 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"lt=
r">I&#39;ve been sharpening my template machinery lately, and with the rece=
nt advent of structured binding declarations, it occurred to me that an acc=
ess method for containers that was capable of returning multiple values as =
a tuple could be really useful.<div><br></div><div>Given that I&#39;m not c=
ertain on my phraseology, I think source code would be ideal, so attached i=
s an example of a string splitting function where the individual results ca=
n be saved off as a structured binding without the use of any temporary var=
iables.</div><div><br></div><div>A few points of discussion (in addition to=
 anything else you guys come up with)</div><div><ul><li><div>I did it this =
time by returning a tuple of values instead of a tuple of references, so th=
at they would not be dangling at the end of the split function. For more co=
mplex types in certain circumstances, there could be reason to have a refer=
ence version that returns the tuple of references (or maybe even a move ver=
sion that moves it&#39;s accessed members out with)</div></li></ul></div></=
div></blockquote><div>This is the biggest &quot;point of discussion&quot; I=
 see with what you&#39;ve made. You write:</div><div><br></div><div><pre st=
yle=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); word-wrap: break-wor=
d; white-space: pre-wrap;">    auto const&amp;[first, last] =3D split(&quot=
;John Smith&quot;, &quot; &quot;).get(0,1);</pre></div><div><br></div><div>=
What this actually does is:</div><div>- Construct a vector&lt;string&gt; of=
 all the substrings in the split</div><div>- Copy two of these substrings i=
nto a tuple&lt;string, string&gt;</div><div>- Bind `first` and `last` to th=
e elements of this tuple</div><div><br></div><div>What we&#39;d like it to =
do is <i>at least</i>:</div><div><div>- Construct a vector&lt;string&gt; of=
 all the substrings in the split</div><div>- Copy two of these substrings i=
nto a tuple&lt;string, string&gt;</div><div>- Bind `first` and `last` to tw=
o of these substrings</div><div><br></div></div><div>with no extra copies. =
But if we try returning a tuple&lt;string&amp;, string&amp;&gt;, we run int=
o dangling-reference problems, as you noticed.</div><div>(And maybe we even=
 want to go further and do something with lazy generators so that we don&#3=
9;t have to allocate that vector&lt;string&gt; to begin with.)</div><div>I =
think the idea as implemented here is too inefficient to be suitable for th=
e STL.</div><div><br></div><div>Orthogonally, I think the idea is not <i>us=
eful</i> enough for the STL either, but that&#39;s a less important and les=
s objective point than the efficiency/lifetime concern.</div><div><br></div=
><div><br></div><div>Also, just a nitpick on your metaprogramming:</div><di=
v><br></div><div><pre style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, =
0); word-wrap: break-word; white-space: pre-wrap;">  /** Magical Get */
  template&lt;typename... Indices&gt;
  auto get(std::size_t i, Indices... indices)
  {
    return std::tuple_cat(get(i), get(indices...));
  }</pre><pre style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); word=
-wrap: break-word; white-space: pre-wrap;"><br><span style=3D"caret-color: =
rgb(0, 0, 0); color: rgb(0, 0, 0); white-space: pre-wrap; font-family: Aria=
l, Helvetica, sans-serif;">You could write simply</span><br></pre><pre styl=
e=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); word-wrap: break-word;=
 white-space: pre-wrap;"><br></pre><pre style=3D"word-wrap: break-word;"><p=
re style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); white-space: pr=
e-wrap; word-wrap: break-word;">  /** Magical Get */
  template&lt;typename... Indices&gt;
  auto get(Indices... indices)
  {
    return std::make_tuple(get(indices)...);
  }</pre><pre style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); whit=
e-space: pre-wrap; word-wrap: break-word;"><br></pre><font face=3D"arial, s=
ans-serif">and it would have the same effect in all relevant respects, but =
without the recursive template instantiations.</font><br></pre><pre style=
=3D"word-wrap: break-word;"><font face=3D"arial, sans-serif"><br></font></p=
re><pre style=3D"word-wrap: break-word;"><font face=3D"arial, sans-serif">F=
or prior art in the area of &quot;take a container and produce a new view o=
nto it by shuffling and/or subsetting its indices,&quot; you might want to =
take a look at std::valarray&#39;s operator[] overloads.</font></pre><pre s=
tyle=3D"word-wrap: break-word;"><font face=3D"arial, sans-serif"><br></font=
></pre><pre style=3D"word-wrap: break-word;"><font face=3D"arial, sans-seri=
f">=E2=80=93Arthur</font></pre></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/67bd9d4b-cec0-4b20-95c5-1bfe201edc92%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/67bd9d4b-cec0-4b20-95c5-1bfe201edc92=
%40isocpp.org</a>.<br />

------=_Part_7840_710818855.1526602830401--

------=_Part_7839_219147667.1526602830400--

.