Topic: Generalizing range based for loops even further


Author: rmn100@gmail.com
Date: Mon, 22 May 2017 21:10:40 -0700 (PDT)
Raw View
------=_Part_1093_329826797.1495512640075
Content-Type: multipart/alternative;
 boundary="----=_Part_1094_443419671.1495512640076"

------=_Part_1094_443419671.1495512640076
Content-Type: text/plain; charset="UTF-8"

C++17 has a new feature that would improve the functionality of range based
for loops to work with begin and end iterators that are not of the same
type as proposed by Eric Niebler here
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html.  This
is a great feature, as it generalizes the range based for loop to fit
scenarios that would otherwise not be possible, essentially making it more
adaptable.

But something like the following is still not possible using the range
based for loop, since the dereferenced iterators must be the same type, and
therefore cannot contain any compile time information
    for (auto ele : std::make_tuple(1, 2)) {
        cout << ele << endl;
    }

Iterating through a tuple requires use of minimal amounts of
metaprogramming, it is easy to write a small helper that would automate
this for us.  But then again, it requires extra work on the programmers
part. A language solution seems to be more intuitive to me - generalize the
range based for loop to the stage where it can accept a range of different
iterator types.

You might be thinking that such a change cannot be made without sacrificing
runtime efficiency in the range based for loop as it expects the same type
for iterators it dereferences.  What I propose is to not use the
operator++() method (the pre-increment member function) to increment
iterators when they contain a trait that signals that they are heterogenous
iterators.  Perhaps this could be enabled with the help of a
preferred_increment iterator tag, which if absent will cause the range
based for loop to default to prefix operator++(), but if present will make
the range based for loop go with the preferred increment approach (which
can either be a post-increment and initialization or a reference
pre-increment).  With this small change the tuple class can be modified to
support iteration.  The iterator for a tuple might look something like the
following

template <typename... Args>
class tuple {
public:

    // The iterator class is templated with an integer that denotes which
    // member of the tuple it must fetch from, the tuple type is included
    // for forwarding reasons
    template <int index, typename TupleType>
    class Iterator {
    public:
        // this tells the range based for loop to not use the operator++()
        // member function to increment the iterator, but rather to use the
        // operator++(int) postfix increment method
        using preferred_increment = std::post_increment_tag;

        // The constructor initializes the iterator with a reference to the
        // tuple
        Iterator(tuple<Args...>& tup_in) : tup{tup_in} {}

        // The dereference operator forwards the tuple and returns the
forwarded
        // result obtained on a call to std::get<>
        decltype(auto) operator*() {
            return std::get<index>(std::forward<TupleType>(this->tup));
        }

        // The iterator only defines a postfix increment, as is needed for
        // heterogenosity
        auto operator++(int) {
            return Iterator<index + 1, TupleType>(this->tup);
        }

        // return a false for iterators that are not of the same type
        template <int index_other, typename TupleType>
        constexpr bool operator!=(const Iterator<index_other, TupleType&) {
            return index_other != index;
        }
    };

    // The begin() member function returns an iterator type that will return
    // lvalue references on dereferencing
    auto begin() & {
        return Iterator<0, tuple<Args...>&>{*this};
    }

    // The begin() member function returns an iterator type that will return
    // rvalue references on dereferencing
    auto begin() && {
        // or Iterator<0, tuple<Args...>>{*this};
        return Iterator<0, tuple<Args...>&&>{*this};
    }

    // The end iterator returns an iterator with the sizeof(Args)... as the
    // index, so any iterator type that reaches it will compare the same
    // The tuple type really doesn't matter here
    auto end() {
        return Iterator<sizeof(Args)..., tuple<Args...>>{*this};
    }
};


And that would allow the range based for loop to increment the iterator
with the heterogenous postfix iterator increment like so
for (auto element : std::make_tuple(1, "some string")) {
    cout << element << endl;
}

Of course making an iterator class for a tuple seems to outweigh the
benefits, but making such a modification to the range based for loop to
generalize it further seems to be a good idea in my mind as it opens up
doors for a whole bunch of other things.  Like iteration through a range
computed at compile time.  The canonical example here could be through the
fibonacci range
for (auto val : std::fibonacci{}) {
    cout << val << endl;
}


or iterate through a function's arguments
template <typename... Args>
void foo(Args&&... args_in) {
    auto args = std::forward_as_tuple(std::forward<Args>(args_in)...);
    for (auto&& arg : args) {
        // ...
    }
}

even something like so will be possible
// compile time iteration through a range of integers
for (auto index : std::make_integer_sequence<int,10>{}) {
    cout << std::get<static_cast<int>(index)>(some_tuple) << endl;
}

Apologies for the mistakes in the code, I didn't actually compile any of
it, it is just a vision of what I hope might come to pass if people like
this idea.

--
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/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org.

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

<div dir=3D"ltr">C++17 has a new feature that would improve the functionali=
ty of range based for loops to work with begin and end iterators that are n=
ot of the same type as proposed by Eric Niebler here http://www.open-std.or=
g/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html. =C2=A0This is a great featu=
re, as it generalizes the range based for loop to fit scenarios that would =
otherwise not be possible, essentially making it more adaptable. =C2=A0<div=
><br></div><div>But something like the following is still not possible usin=
g the range based for loop, since the dereferenced iterators must be the sa=
me type, and therefore cannot contain any compile time information</div><di=
v class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bord=
er: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"pr=
ettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">=C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">for</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> el=
e </span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">make_tuple</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 cout </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 ele </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&=
lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> endl</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></cod=
e></div><div><br>Iterating through a tuple requires use of minimal amounts =
of metaprogramming, it is easy to write a small helper that would automate =
this for us. =C2=A0But then again, it requires extra work on the programmer=
s part. A language solution seems to be more intuitive to me - generalize t=
he range based for loop to the stage where it can accept a range of differe=
nt iterator types.=C2=A0</div><div><br></div><div>You might be thinking tha=
t such a change cannot be made without sacrificing runtime efficiency in th=
e range based for loop as it expects the same type for iterators it derefer=
ences. =C2=A0What I propose is to not use the <font face=3D"courier new, mo=
nospace">operator++()</font>=C2=A0method (the pre-increment member function=
) to increment iterators when they contain a trait that signals that they a=
re heterogenous iterators. =C2=A0Perhaps this could be enabled with the hel=
p of a <font face=3D"courier new, monospace">preferred_increment</font><fon=
t face=3D"arial, sans-serif">=C2=A0iterator tag, which if absent will cause=
 the range based for loop to default to prefix operator++(), but if present=
 will make the range based for loop go with the preferred increment approac=
h (which can either be a post-increment and initialization or a reference p=
re-increment). =C2=A0With this small change the tuple class can be modified=
 to support iteration. =C2=A0The iterator for a tuple might look something =
like the following</font></div><div><font face=3D"arial, sans-serif"><br></=
font></div><div class=3D"prettyprint" style=3D"background-color: rgb(250, 2=
50, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><co=
de class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color=
: #008;" class=3D"styled-by-prettify">template</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">typename</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettif=
y">Args</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> tuple </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">public</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0<br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color: #800;" class=3D"styled-by-prettify">// The iterator cla=
ss is templated with an integer that denotes which </span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">/</span><font color=3D"#00=
0000"><span style=3D"color: #800;" class=3D"styled-by-prettify">/ member of=
 the tuple it must fetch from, the tuple type is included</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span></font><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 </span><span =
style=3D"color: #800;" class=3D"styled-by-prettify">// for forwarding reaso=
ns</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>template</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span=
><font color=3D"#000088"><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> index</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">TupleType</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&gt;</span></font><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Iterator</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">public</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:=
 #800;" class=3D"styled-by-prettify">// this tells the range based for loop=
 to not use the operator++()</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"col=
or: #800;" class=3D"styled-by-prettify">// member function to increment the=
 iterator, but rather to use the </span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// operator++(int) postfix i=
ncrement method</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">using</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> preferred_increment </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><font color=3D"#000000"><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">post_increment_tag</span></font><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
 The constructor initializes the iterator with a reference to the </span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-pretti=
fy">// tuple</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Iterator</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">tuple</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-pretti=
fy">Args</span><span style=3D"color: #660;" class=3D"styled-by-prettify">..=
..&gt;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 tup_in</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> tup</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">tup_in</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">{}</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800;" c=
lass=3D"styled-by-prettify">// The dereference operator forwards the tuple =
and returns the forwarded </span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">// result obtained on a call to std::=
get&lt;&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">decltype</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">operator<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">*()</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>return</span><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: #008;" class=3D"styled-by-prettify">get</span><span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify">&lt;index&gt;</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">forward</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">TupleType</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;(</span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">this</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">-&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">tup</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>));</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 <br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </=
span><span style=3D"color: #800;" class=3D"styled-by-prettify">// The itera=
tor only defines a postfix increment, as is needed for </span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// het=
erogenosity</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">operator</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">++(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Iterator<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">index </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">+</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by=
-prettify">TupleType</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&gt;(</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">this</span><span style=3D"color: #660;" class=3D"styled-by-prettify">-=
&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">tup</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">// return a false for iterators that are not of the same =
type</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">template</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&lt;</span><font color=3D"#000088"><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> index_other</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">typename</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #606;" class=3D"styled-by-prettify">TupleType=
</span></font><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">constexpr</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">bool</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">!=3D(</span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><font color=3D=
"#660066"><span style=3D"color: #606;" class=3D"styled-by-prettify">Iterato=
r</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">index_other</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">TupleType</span></font><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&amp;)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> index_other <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">!=3D</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> index</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0=
 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//=
 The begin() member function returns an iterator type that will return</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// lva=
lue references on dereferencing</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">begin</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #606;" class=3D"styled-by-prettify">Iterator</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span styl=
e=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> tuple</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"=
styled-by-prettify">Args</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">...&gt;&amp;&gt;{*</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">this</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 <br>=C2=A0 =C2=A0 </span><span style=3D"color: #=
800;" class=3D"styled-by-prettify">// The begin() member function returns a=
n iterator type that will return</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// rvalue references on dereferencing</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">begin</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:=
 #800;" class=3D"styled-by-prettify">// or Iterator&lt;0, tuple&lt;Args...&=
gt;&gt;{*this}; </span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Iterator</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&lt;</span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> tuple</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><spa=
n style=3D"color: #606;" class=3D"styled-by-prettify">Args</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">...&gt;&amp;&amp;&gt;{*</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">this</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 </span=
><span style=3D"color: #800;" class=3D"styled-by-prettify">// The end itera=
tor returns an iterator with the sizeof(Args)... as the</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #800;" class=3D"styled-by-prettify">// index, so any ite=
rator type that reaches it will compare the same</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// The tuple type really doe=
sn&#39;t matter here</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">end</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #606;" class=3D"styled-by-prettify">Iterator</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">sizeof</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
606;" class=3D"styled-by-prettify">Args</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)...,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> tuple</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"styled=
-by-prettify">Args</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">...&gt;&gt;{*</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">this</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span></d=
iv></code></div><div><font face=3D"arial, sans-serif"><br></font></div><div=
><font face=3D"arial, sans-serif">And that would allow the range based for =
loop to increment the iterator with the heterogenous postfix iterator incre=
ment like so</font></div><div class=3D"prettyprint" style=3D"background-col=
or: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: br=
eak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span =
style=3D"color: #008;" class=3D"styled-by-prettify">for</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> element </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>make_tuple</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #080;" class=3D"styled-by-prettify">&quot;some string&quot;</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">))</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 cout </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> element </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> endl</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span></div></code></div><div><br></div><div><div>Of course m=
aking an iterator class for a tuple seems to outweigh the benefits, but mak=
ing such a modification to the range based for loop to generalize it furthe=
r seems to be a good idea in my mind as it opens up doors for a whole bunch=
 of other things. =C2=A0Like iteration through a range computed at compile =
time. =C2=A0The canonical example here could be through the fibonacci range=
</div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 1=
87); background-color: rgb(250, 250, 250); word-wrap: break-word;"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">for</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> val </span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">fibonacci</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">{})</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 cout </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> val </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> endl</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span></div><div><span class=3D"styled-by-prettify" style=3D"color: rg=
b(102, 102, 0);"><br></span></div></code></div></div><div><br></div><div>or=
 iterate through a function&#39;s arguments</div><div class=3D"prettyprint"=
 style=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, =
187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">template</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">Args</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #606;" class=3D"styled-by-pretti=
fy">Args</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&a=
mp;&amp;...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> args_in</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> args </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">forward_as_tuple</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">forward</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-prettify">=
Args</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">args_in</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">)...);</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">for</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> arg </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> args</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by=
-prettify">// ...</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n></div></code></div><div><br></div><div>even something like so will be pos=
sible</div><div><div class=3D"prettyprint" style=3D"background-color: rgb(2=
50, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word;=
"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"=
color: #800;" class=3D"styled-by-prettify">// compile time iteration throug=
h a range of integers</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">for</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><fo=
nt color=3D"#000088"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i=
ndex </span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">make_integer_sequence</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">10</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&gt;{})</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 cout </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">get</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">sta=
tic_cast</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&l=
t;int&gt;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">index</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">)&gt;(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">some_tuple</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> endl</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span></font></div></code></div></div><div><br></div><d=
iv>Apologies for the mistakes in the code, I didn&#39;t actually compile an=
y of it, it is just a vision of what I hope might come to pass if people li=
ke this idea.=C2=A0</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/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96=
%40isocpp.org</a>.<br />

------=_Part_1094_443419671.1495512640076--

------=_Part_1093_329826797.1495512640075--

.


Author: Avi Kivity <avi@scylladb.com>
Date: Tue, 23 May 2017 09:30:01 +0300
Raw View
This is a multi-part message in MIME format.
--------------5435BF421D72AF7326A85E86
Content-Type: text/plain; charset="UTF-8"; format=flowed

On 05/23/2017 07:10 AM, rmn100@gmail.com wrote:
> C++17 has a new feature that would improve the functionality of range
> based for loops to work with begin and end iterators that are not of
> the same type as proposed by Eric Niebler here
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html.
>  This is a great feature, as it generalizes the range based for loop
> to fit scenarios that would otherwise not be possible, essentially
> making it more adaptable.
>
> But something like the following is still not possible using the range
> based for loop, since the dereferenced iterators must be the same
> type, and therefore cannot contain any compile time information
> |
> for(autoele :std::make_tuple(1,2)){
>         cout <<ele <<endl;
> }
> |
>


Perhaps:


     for constexpr (auto element : std::tuple(1, "a")) {
         std::cout << element << std::endl;
     }

The rules can then be relaxed that operator++ can return new types; the
compiler will essentially unroll the loop if that's the case.

> Iterating through a tuple requires use of minimal amounts of
> metaprogramming, it is easy to write a small helper that would
> automate this for us.  But then again, it requires extra work on the
> programmers part. A language solution seems to be more intuitive to me
> - generalize the range based for loop to the stage where it can accept
> a range of different iterator types.
>
> You might be thinking that such a change cannot be made without
> sacrificing runtime efficiency in the range based for loop as it
> expects the same type for iterators it dereferences.  What I propose
> is to not use the operator++() method (the pre-increment member
> function) to increment iterators when they contain a trait that
> signals that they are heterogenous iterators.  Perhaps this could be
> enabled with the help of a preferred_increment iterator tag, which if
> absent will cause the range based for loop to default to prefix
> operator++(), but if present will make the range based for loop go
> with the preferred increment approach (which can either be a
> post-increment and initialization or a reference pre-increment).  With
> this small change the tuple class can be modified to support
> iteration.  The iterator for a tuple might look something like the
> following
>
> |
> template<typename...Args>
> classtuple {
> public:
>
> // The iterator class is templated with an integer that denotes which
> // member of the tuple it must fetch from, the tuple type is included
> // for forwarding reasons
> template<intindex,typenameTupleType>
> classIterator{
> public:
> // this tells the range based for loop to not use the operator++()
> // member function to increment the iterator, but rather to use the
> // operator++(int) postfix increment method
> usingpreferred_increment =std::post_increment_tag;
>
> // The constructor initializes the iterator with a reference to the
> // tuple
> Iterator(tuple<Args...>&tup_in):tup{tup_in}{}
>
> // The dereference operator forwards the tuple and returns the forwarded
> // result obtained on a call to std::get<>
> decltype(auto)operator*(){
> returnstd::get<index>(std::forward<TupleType>(this->tup));
> }
>
> // The iterator only defines a postfix increment, as is needed for
> // heterogenosity
> autooperator++(int){
> returnIterator<index +1,TupleType>(this->tup);
> }
>
> // return a false for iterators that are not of the same type
> template<intindex_other,typenameTupleType>
> constexprbooloperator!=(constIterator<index_other,TupleType&){
> returnindex_other !=index;
> }
> };
>
> // The begin() member function returns an iterator type that will return
> // lvalue references on dereferencing
> autobegin()&{
> returnIterator<0,tuple<Args...>&>{*this};
> }
>
> // The begin() member function returns an iterator type that will return
> // rvalue references on dereferencing
> autobegin()&&{
> // or Iterator<0, tuple<Args...>>{*this};
> returnIterator<0,tuple<Args...>&&>{*this};
> }
>
> // The end iterator returns an iterator with the sizeof(Args)... as the
> // index, so any iterator type that reaches it will compare the same
> // The tuple type really doesn't matter here
> autoend(){
> returnIterator<sizeof(Args)...,tuple<Args...>>{*this};
> }
> };
>
> |
>
> And that would allow the range based for loop to increment the
> iterator with the heterogenous postfix iterator increment like so
> |
> for(autoelement :std::make_tuple(1,"some string")){
>     cout <<element <<endl;
> }
> |
>
> Of course making an iterator class for a tuple seems to outweigh the
> benefits, but making such a modification to the range based for loop
> to generalize it further seems to be a good idea in my mind as it
> opens up doors for a whole bunch of other things.  Like iteration
> through a range computed at compile time.  The canonical example here
> could be through the fibonacci range
> |
> for(autoval :std::fibonacci{}){
>     cout <<val <<endl;
> }
>
> |
>
> or iterate through a function's arguments
> |
> template<typename...Args>
> voidfoo(Args&&...args_in){
> autoargs =std::forward_as_tuple(std::forward<Args>(args_in)...);
> for(auto&&arg :args){
> // ...
> }
> }
> |
>
> even something like so will be possible
> |
> // compile time iteration through a range of integers
> for(autoindex :std::make_integer_sequence<int,10>{}){
>     cout <<std::get<static_cast<int>(index)>(some_tuple)<<endl;
> }
> |
>
> Apologies for the mistakes in the code, I didn't actually compile any
> of it, it is just a vision of what I hope might come to pass if people
> like this idea.
> --
> 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
> <mailto:std-proposals+unsubscribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org
> <mailto:std-proposals@isocpp.org>.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org?utm_medium=email&utm_source=footer>.


--
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/c2b44e2f-a47d-66af-dfaf-1120ea28577e%40scylladb.com.

--------------5435BF421D72AF7326A85E86
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8=
">
  </head>
  <body text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div class=3D"moz-cite-prefix">On 05/23/2017 07:10 AM,
      <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:rmn100@gmail.com=
">rmn100@gmail.com</a> wrote:<br>
    </div>
    <blockquote type=3D"cite"
      cite=3D"mid:05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96@isocpp.org">
      <div dir=3D"ltr">C++17 has a new feature that would improve the
        functionality of range based for loops to work with begin and
        end iterators that are not of the same type as proposed by Eric
        Niebler here
        <a class=3D"moz-txt-link-freetext" href=3D"http://www.open-std.org/=
jtc1/sc22/wg21/docs/papers/2016/p0184r0.html">http://www.open-std.org/jtc1/=
sc22/wg21/docs/papers/2016/p0184r0.html</a>.
        =C2=A0This is a great feature, as it generalizes the range based fo=
r
        loop to fit scenarios that would otherwise not be possible,
        essentially making it more adaptable. =C2=A0
        <div><br>
        </div>
        <div>But something like the following is still not possible
          using the range based for loop, since the dereferenced
          iterators must be the same type, and therefore cannot contain
          any compile time information</div>
        <div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
          250); border: 1px solid rgb(187, 187, 187); word-wrap:
          break-word;"><code class=3D"prettyprint">
            <div class=3D"subprettyprint"><span style=3D"color: #000;"
                class=3D"styled-by-prettify">=C2=A0 =C2=A0 </span><span
                style=3D"color: #008;" class=3D"styled-by-prettify">for</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> ele </=
span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">:</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify">make_tu=
ple</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #066;" class=3D"styled-by-prettify">1</span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #066;" class=3D"styled-by-prettify">2</span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">))</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 cout </span><span style=3D"colo=
r: #660;"
                class=3D"styled-by-prettify">&lt;&lt;</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> ele </=
span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt=
;</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> endl</=
span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">}</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
      </div>
    </blockquote>
    <br>
    <br>
    Perhaps:<br>
    <br>
    <br>
    =C2=A0=C2=A0=C2=A0 for constexpr (auto element : std::tuple(1, "a")) {<=
br>
    =C2=A0 =C2=A0 =C2=A0 =C2=A0 std::cout &lt;&lt; element &lt;&lt; std::en=
dl; <br>
    =C2=A0=C2=A0=C2=A0 }<br>
    <br>
    The rules can then be relaxed that operator++ can return new types;
    the compiler will essentially unroll the loop if that's the case. <br>
    <br>
    <blockquote type=3D"cite"
      cite=3D"mid:05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96@isocpp.org">
      <div dir=3D"ltr">
        <div>Iterating through a tuple requires use of minimal amounts
          of metaprogramming, it is easy to write a small helper that
          would automate this for us. =C2=A0But then again, it requires ext=
ra
          work on the programmers part. A language solution seems to be
          more intuitive to me - generalize the range based for loop to
          the stage where it can accept a range of different iterator
          types.=C2=A0</div>
        <div><br>
        </div>
        <div>You might be thinking that such a change cannot be made
          without sacrificing runtime efficiency in the range based for
          loop as it expects the same type for iterators it
          dereferences. =C2=A0What I propose is to not use the <font
            face=3D"courier new, monospace">operator++()</font>=C2=A0method
          (the pre-increment member function) to increment iterators
          when they contain a trait that signals that they are
          heterogenous iterators. =C2=A0Perhaps this could be enabled with
          the help of a <font face=3D"courier new, monospace">preferred_inc=
rement</font><font
            face=3D"arial, sans-serif">=C2=A0iterator tag, which if absent =
will
            cause the range based for loop to default to prefix
            operator++(), but if present will make the range based for
            loop go with the preferred increment approach (which can
            either be a post-increment and initialization or a reference
            pre-increment). =C2=A0With this small change the tuple class ca=
n
            be modified to support iteration. =C2=A0The iterator for a tupl=
e
            might look something like the following</font></div>
        <div><font face=3D"arial, sans-serif"><br>
          </font></div>
        <div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
          250); border: 1px solid rgb(187, 187, 187); word-wrap:
          break-word;"><code class=3D"prettyprint">
            <div class=3D"subprettyprint"><span style=3D"color: #008;"
                class=3D"styled-by-prettify">template</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #008;" class=3D"styled-by-prettify">typenam=
e</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">...</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">class</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> tuple =
</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">public</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">:</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0<br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #800;"
                class=3D"styled-by-prettify">// The iterator class is
                templated with an integer that denotes which </span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #800;"
                class=3D"styled-by-prettify">/</span><font color=3D"#000000=
"><span
                  style=3D"color: #800;" class=3D"styled-by-prettify">/
                  member of the tuple it must fetch from, the tuple type
                  is included</span><span style=3D"color: #000;"
                  class=3D"styled-by-prettify"><br>
                </span></font><span style=3D"color: #000;"
                class=3D"styled-by-prettify">=C2=A0 =C2=A0 </span><span
                style=3D"color: #800;" class=3D"styled-by-prettify">// for
                forwarding reasons</span><span style=3D"color: #000;"
                class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">template</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><font
                color=3D"#000088"><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">int</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> inde=
x</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">typen=
ame</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">Tuple=
Type</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&gt;<=
/span></font><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">class</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Iterato=
r</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">public</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">:</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// this tells the range based
                for loop to not use the operator++()</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// member function to
                increment the iterator, but rather to use the </span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// operator++(int) postfix
                increment method</span><span style=3D"color: #000;"
                class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;"
                class=3D"styled-by-prettify">using</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify">
                preferred_increment </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">=3D</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> std</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><font
                color=3D"#000000"><span style=3D"color: #000;"
                  class=3D"styled-by-prettify">post_increment_tag</span></f=
ont><span
                style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// The constructor
                initializes the iterator with a reference to the </span><sp=
an
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// tuple</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #6=
06;"
                class=3D"styled-by-prettify">Iterator</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify">tuple</=
span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">...&gt;=
&amp;</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> tup_in=
</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">:</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> tup</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify">tup_in<=
/span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">}</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{}</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// The dereference operator
                forwards the tuple and returns the forwarded </span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// result obtained on a call
                to std::get&lt;&gt;</span><span style=3D"color: #000;"
                class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;"
                class=3D"styled-by-prettify">decltype</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">operato=
r</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">*()</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color: #008;"
                class=3D"styled-by-prettify">return</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
                style=3D"color: #008;" class=3D"styled-by-prettify">get</sp=
an><span
                style=3D"color: #080;" class=3D"styled-by-prettify">&lt;ind=
ex&gt;</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify">std</sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify">forward=
</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #606;" class=3D"styled-by-prettify">TupleTy=
pe</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</=
span><span
                style=3D"color: #008;" class=3D"styled-by-prettify">this</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">-&gt;</=
span><span
                style=3D"color: #000;" class=3D"styled-by-prettify">tup</sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">));</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #6=
60;"
                class=3D"styled-by-prettify">}</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// The iterator only defines
                a postfix increment, as is needed for </span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// heterogenosity</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;"
                class=3D"styled-by-prettify">auto</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">operato=
r</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">++(</sp=
an><span
                style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color: #008;"
                class=3D"styled-by-prettify">return</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Iterato=
r</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify">index <=
/span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">+</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #066;" class=3D"styled-by-prettify">1</span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">TupleTy=
pe</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</=
span><span
                style=3D"color: #008;" class=3D"styled-by-prettify">this</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">-&gt;</=
span><span
                style=3D"color: #000;" class=3D"styled-by-prettify">tup</sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">);</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #6=
60;"
                class=3D"styled-by-prettify">}</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// return a false for
                iterators that are not of the same type</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;"
                class=3D"styled-by-prettify">template</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><font
                color=3D"#000088"><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">int</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">
                  index_other</span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">,</span><span style=3D"color=
:
                  #000;" class=3D"styled-by-prettify"> </span><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">typen=
ame</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">Tuple=
Type</span></font><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;"
                class=3D"styled-by-prettify">constexpr</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">bool</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">operato=
r</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">!=3D(</=
span><span
                style=3D"color: #008;" class=3D"styled-by-prettify">const</=
span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><font
                color=3D"#660066"><span style=3D"color: #606;"
                  class=3D"styled-by-prettify">Iterator</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;<=
/span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">index=
_other</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #606;" class=3D"styled-by-prettify">Tuple=
Type</span></font><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&amp;)<=
/span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color: #008;"
                class=3D"styled-by-prettify">return</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify">
                index_other </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">!=3D</span><span style=3D"colo=
r:
                #000;" class=3D"styled-by-prettify"> index</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #6=
60;"
                class=3D"styled-by-prettify">}</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">};</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                <br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #800;"
                class=3D"styled-by-prettify">// The begin() member
                function returns an iterator type that will return</span><s=
pan
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #800;"
                class=3D"styled-by-prettify">// lvalue references on
                dereferencing</span><span style=3D"color: #000;"
                class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">auto</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">begin</=
span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">()</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</=
span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;"
                class=3D"styled-by-prettify">return</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Iterato=
r</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #066;" class=3D"styled-by-prettify">0</span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> tuple<=
/span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">...&gt;=
&amp;&gt;{*</span><span
                style=3D"color: #008;" class=3D"styled-by-prettify">this</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">};</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">}</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 <br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #800;"
                class=3D"styled-by-prettify">// The begin() member
                function returns an iterator type that will return</span><s=
pan
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #800;"
                class=3D"styled-by-prettify">// rvalue references on
                dereferencing</span><span style=3D"color: #000;"
                class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">auto</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">begin</=
span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">()</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&a=
mp;</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// or Iterator&lt;0,
                tuple&lt;Args...&gt;&gt;{*this}; </span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;"
                class=3D"styled-by-prettify">return</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Iterato=
r</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #066;" class=3D"styled-by-prettify">0</span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> tuple<=
/span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">...&gt;=
&amp;&amp;&gt;{*</span><span
                style=3D"color: #008;" class=3D"styled-by-prettify">this</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">};</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">}</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                <br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #800;"
                class=3D"styled-by-prettify">// The end iterator returns
                an iterator with the sizeof(Args)... as the</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #800;"
                class=3D"styled-by-prettify">// index, so any iterator
                type that reaches it will compare the same</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #800;"
                class=3D"styled-by-prettify">// The tuple type really
                doesn't matter here</span><span style=3D"color: #000;"
                class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">auto</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">end</sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">()</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;"
                class=3D"styled-by-prettify">return</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Iterato=
r</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #008;" class=3D"styled-by-prettify">sizeof<=
/span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)...,</=
span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> tuple<=
/span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">...&gt;=
&gt;{*</span><span
                style=3D"color: #008;" class=3D"styled-by-prettify">this</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">};</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">}</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">};</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                <br>
              </span></div>
          </code></div>
        <div><font face=3D"arial, sans-serif"><br>
          </font></div>
        <div><font face=3D"arial, sans-serif">And that would allow the
            range based for loop to increment the iterator with the
            heterogenous postfix iterator increment like so</font></div>
        <div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
          250); border: 1px solid rgb(187, 187, 187); word-wrap:
          break-word;"><code class=3D"prettyprint">
            <div class=3D"subprettyprint"><span style=3D"color: #008;"
                class=3D"styled-by-prettify">for</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> </span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> elemen=
t
              </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">:</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"> std</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify">make_tu=
ple</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #066;" class=3D"styled-by-prettify">1</span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #080;" class=3D"styled-by-prettify">"some
                string"</span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">))</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"> </span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 cout </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">&lt;&lt;</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> elemen=
t
              </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">&lt;&lt;</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> endl</=
span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">}</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
        <div>
          <div>Of course making an iterator class for a tuple seems to
            outweigh the benefits, but making such a modification to the
            range based for loop to generalize it further seems to be a
            good idea in my mind as it opens up doors for a whole bunch
            of other things. =C2=A0Like iteration through a range computed =
at
            compile time. =C2=A0The canonical example here could be through
            the fibonacci range</div>
          <div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
            187, 187); background-color: rgb(250, 250, 250); word-wrap:
            break-word;"><code class=3D"prettyprint">
              <div class=3D"subprettyprint"><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">for</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span
                  style=3D"color: #008;" class=3D"styled-by-prettify">auto<=
/span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> val =
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">:</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> std<=
/span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span
                  style=3D"color: #000;" class=3D"styled-by-prettify">fibon=
acci</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">{})</=
span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                  =C2=A0 =C2=A0 cout </span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">&lt;&lt;</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> val =
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&=
lt;</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> endl=
</span><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                </span><span style=3D"color: #660;"
                  class=3D"styled-by-prettify">}</span><span style=3D"color=
:
                  #000;" class=3D"styled-by-prettify"><br>
                </span></div>
              <div><span class=3D"styled-by-prettify" style=3D"color:
                  rgb(102, 102, 0);"><br>
                </span></div>
            </code></div>
        </div>
        <div><br>
        </div>
        <div>or iterate through a function's arguments</div>
        <div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
          250); border: 1px solid rgb(187, 187, 187); word-wrap:
          break-word;"><code class=3D"prettyprint">
            <div class=3D"subprettyprint"><span style=3D"color: #008;"
                class=3D"styled-by-prettify">template</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #008;" class=3D"styled-by-prettify">typenam=
e</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">...</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">void</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> foo</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&a=
mp;...</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> args_i=
n</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">auto</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> args <=
/span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify">forward=
_as_tuple</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify">std</sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify">forward=
</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</=
span><span
                style=3D"color: #000;" class=3D"styled-by-prettify">args_in=
</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)...);<=
/span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">for</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> </span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&a=
mp;</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> arg </=
span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">:</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> args</=
span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #8=
00;"
                class=3D"styled-by-prettify">// ...</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">}</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">}</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
        <div>even something like so will be possible</div>
        <div>
          <div class=3D"prettyprint" style=3D"background-color: rgb(250,
            250, 250); border: 1px solid rgb(187, 187, 187); word-wrap:
            break-word;"><code class=3D"prettyprint">
              <div class=3D"subprettyprint"><span style=3D"color: #800;"
                  class=3D"styled-by-prettify">// compile time iteration
                  through a range of integers</span><span style=3D"color:
                  #000;" class=3D"styled-by-prettify"><br>
                </span><span style=3D"color: #008;"
                  class=3D"styled-by-prettify">for</span><span
                  style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span
                  style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><font
                  color=3D"#000088"><span style=3D"color: #008;"
                    class=3D"styled-by-prettify">auto</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    index </span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">:</span><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">mak=
e_integer_sequence</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">&lt=
;</span><span
                    style=3D"color: #008;" class=3D"styled-by-prettify">int=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span
                    style=3D"color: #066;" class=3D"styled-by-prettify">10<=
/span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">&gt=
;{})</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                    =C2=A0 =C2=A0 cout </span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">&lt;&lt;</span><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: #008;" class=3D"styled-by-prettify">get=
</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">&lt=
;</span><span
                    style=3D"color: #008;" class=3D"styled-by-prettify">sta=
tic_cast</span><span
                    style=3D"color: #080;" class=3D"styled-by-prettify">&lt=
;int&gt;</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">ind=
ex</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">)&g=
t;(</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">som=
e_tuple</span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">)</=
span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span
                    style=3D"color: #660;" class=3D"styled-by-prettify">&lt=
;&lt;</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify">
                    endl</span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">;</span><span
                    style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>
                  </span><span style=3D"color: #660;"
                    class=3D"styled-by-prettify">}</span></font></div>
            </code></div>
        </div>
        <div><br>
        </div>
        <div>Apologies for the mistakes in the code, I didn't actually
          compile any of it, it is just a vision of what I hope might
          come to pass if people like this idea.=C2=A0</div>
      </div>
      -- <br>
      You received this message because you are subscribed to the Google
      Groups "ISO C++ Standard - Future Proposals" group.<br>
      To unsubscribe from this group and stop receiving emails from it,
      send an email to <a
        href=3D"mailto:std-proposals+unsubscribe@isocpp.org"
        moz-do-not-send=3D"true">std-proposals+unsubscribe@isocpp.org</a>.<=
br>
      To post to this group, send email to <a
        href=3D"mailto:std-proposals@isocpp.org" moz-do-not-send=3D"true">s=
td-proposals@isocpp.org</a>.<br>
      To view this discussion on the web visit <a
href=3D"https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/05e067=
5e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org?utm_medium=3Demail&amp;utm_sour=
ce=3Dfooter"
        moz-do-not-send=3D"true">https://groups.google.com/a/isocpp.org/d/m=
sgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org</a>.<b=
r>
    </blockquote>
    <p><br>
    </p>
  </body>
</html>

<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/c2b44e2f-a47d-66af-dfaf-1120ea28577e%=
40scylladb.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.googl=
e.com/a/isocpp.org/d/msgid/std-proposals/c2b44e2f-a47d-66af-dfaf-1120ea2857=
7e%40scylladb.com</a>.<br />

--------------5435BF421D72AF7326A85E86--

.


Author: Anthony Hall <anthrond@gmail.com>
Date: Tue, 23 May 2017 00:07:29 -0700 (PDT)
Raw View
------=_Part_3161_829625352.1495523250057
Content-Type: multipart/alternative;
 boundary="----=_Part_3162_1146729875.1495523250059"

------=_Part_3162_1146729875.1495523250059
Content-Type: text/plain; charset="UTF-8"

You may already be aware of the boost::hana library, but if not: part of
its design intent is to provide facilities and algorithms for traversal of
heterogeneously-typed containers much like what's being proposed.  Of
course, as a C++14 library-based solution, it can't always offer the kind
of syntactic sugar that's been proposed here with `for constexpr` or these
expansions of operator++ overloads.

On Tuesday, May 23, 2017 at 12:30:12 AM UTC-6, Avi Kivity wrote:
>
> On 05/23/2017 07:10 AM, rmn...@gmail.com <javascript:> wrote:
>
> C++17 has a new feature that would improve the functionality of range
> based for loops to work with begin and end iterators that are not of the
> same type as proposed by Eric Niebler here
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html.
>  This is a great feature, as it generalizes the range based for loop to fit
> scenarios that would otherwise not be possible, essentially making it more
> adaptable.
>
> But something like the following is still not possible using the range
> based for loop, since the dereferenced iterators must be the same type, and
> therefore cannot contain any compile time information
>     for (auto ele : std::make_tuple(1, 2)) {
>         cout << ele << endl;
>     }
>
>
>
> Perhaps:
>
>
>     for constexpr (auto element : std::tuple(1, "a")) {
>         std::cout << element << std::endl;
>     }
>
> The rules can then be relaxed that operator++ can return new types; the
> compiler will essentially unroll the loop if that's the case.
>
> Iterating through a tuple requires use of minimal amounts of
> metaprogramming, it is easy to write a small helper that would automate
> this for us.  But then again, it requires extra work on the programmers
> part. A language solution seems to be more intuitive to me - generalize the
> range based for loop to the stage where it can accept a range of different
> iterator types.
>
> You might be thinking that such a change cannot be made without
> sacrificing runtime efficiency in the range based for loop as it expects
> the same type for iterators it dereferences.  What I propose is to not use
> the operator++() method (the pre-increment member function) to increment
> iterators when they contain a trait that signals that they are heterogenous
> iterators.  Perhaps this could be enabled with the help of a
> preferred_increment iterator tag, which if absent will cause the range
> based for loop to default to prefix operator++(), but if present will make
> the range based for loop go with the preferred increment approach (which
> can either be a post-increment and initialization or a reference
> pre-increment).  With this small change the tuple class can be modified to
> support iteration.  The iterator for a tuple might look something like the
> following
>
> template <typename... Args>
> class tuple {
> public:
>
>     // The iterator class is templated with an integer that denotes which
>     // member of the tuple it must fetch from, the tuple type is included
>     // for forwarding reasons
>     template <int index, typename TupleType>
>     class Iterator {
>     public:
>         // this tells the range based for loop to not use the operator++()
>         // member function to increment the iterator, but rather to use
> the
>         // operator++(int) postfix increment method
>         using preferred_increment = std::post_increment_tag;
>
>         // The constructor initializes the iterator with a reference to
> the
>         // tuple
>         Iterator(tuple<Args...>& tup_in) : tup{tup_in} {}
>
>         // The dereference operator forwards the tuple and returns the
> forwarded
>         // result obtained on a call to std::get<>
>         decltype(auto) operator*() {
>             return std::get<index>(std::forward<TupleType>(this->tup));
>         }
>
>         // The iterator only defines a postfix increment, as is needed
> for
>         // heterogenosity
>         auto operator++(int) {
>             return Iterator<index + 1, TupleType>(this->tup);
>         }
>
>         // return a false for iterators that are not of the same type
>         template <int index_other, typename TupleType>
>         constexpr bool operator!=(const Iterator<index_other, TupleType&)
> {
>             return index_other != index;
>         }
>     };
>
>     // The begin() member function returns an iterator type that will
> return
>     // lvalue references on dereferencing
>     auto begin() & {
>         return Iterator<0, tuple<Args...>&>{*this};
>     }
>
>     // The begin() member function returns an iterator type that will
> return
>     // rvalue references on dereferencing
>     auto begin() && {
>         // or Iterator<0, tuple<Args...>>{*this};
>         return Iterator<0, tuple<Args...>&&>{*this};
>     }
>
>     // The end iterator returns an iterator with the sizeof(Args)... as
> the
>     // index, so any iterator type that reaches it will compare the same
>     // The tuple type really doesn't matter here
>     auto end() {
>         return Iterator<sizeof(Args)..., tuple<Args...>>{*this};
>     }
> };
>
>
> And that would allow the range based for loop to increment the iterator
> with the heterogenous postfix iterator increment like so
> for (auto element : std::make_tuple(1, "some string")) {
>     cout << element << endl;
> }
>
> Of course making an iterator class for a tuple seems to outweigh the
> benefits, but making such a modification to the range based for loop to
> generalize it further seems to be a good idea in my mind as it opens up
> doors for a whole bunch of other things.  Like iteration through a range
> computed at compile time.  The canonical example here could be through the
> fibonacci range
> for (auto val : std::fibonacci{}) {
>     cout << val << endl;
> }
>
>
> or iterate through a function's arguments
> template <typename... Args>
> void foo(Args&&... args_in) {
>     auto args = std::forward_as_tuple(std::forward<Args>(args_in)...);
>     for (auto&& arg : args) {
>         // ...
>     }
> }
>
> even something like so will be possible
> // compile time iteration through a range of integers
> for (auto index : std::make_integer_sequence<int,10>{}) {
>     cout << std::get<static_cast<int>(index)>(some_tuple) << endl;
> }
>
> Apologies for the mistakes in the code, I didn't actually compile any of
> it, it is just a vision of what I hope might come to pass if people like
> this idea.
> --
> 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-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
>
>

--
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/3f5d11c8-3d0f-41ad-91eb-328186e981ad%40isocpp.org.

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

<div dir=3D"ltr">You may already be aware of the boost::hana library, but i=
f not: part of its design intent is to provide facilities and algorithms fo=
r traversal of heterogeneously-typed containers much like what&#39;s being =
proposed. =C2=A0Of course, as a C++14 library-based solution, it can&#39;t =
always offer the kind of syntactic sugar that&#39;s been proposed here with=
 `for constexpr` or these expansions of operator++ overloads.<br><br>On Tue=
sday, May 23, 2017 at 12:30:12 AM UTC-6, Avi Kivity wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div>On 05/23/2017 07:10 AM,
      <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"OU=
VYCOj0AwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#3=
9;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;"=
>rmn...@gmail.com</a> wrote:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">C++17 has a new feature that would improve the
        functionality of range based for loops to work with begin and
        end iterators that are not of the same type as proposed by Eric
        Niebler here
        <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/=
p0184r0.html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=
=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1=
%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0184r0.html\x26sa\x3dD\x26sntz\x3d=
1\x26usg\x3dAFQjCNHsm16utECLKaIF1azvSKcFVZwR1g&#39;;return true;" onclick=
=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-s=
td.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0184r0.html\x26sa\x3d=
D\x26sntz\x3d1\x26usg\x3dAFQjCNHsm16utECLKaIF1azvSKcFVZwR1g&#39;;return tru=
e;">http://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2016/<wbr>p0184=
r0.html</a>.
        =C2=A0This is a great feature, as it generalizes the range based fo=
r
        loop to fit scenarios that would otherwise not be possible,
        essentially making it more adaptable. =C2=A0
        <div><br>
        </div>
        <div>But something like the following is still not possible
          using the range based for loop, since the dereferenced
          iterators must be the same type, and therefore cannot contain
          any compile time information</div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#000">=C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">for</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">(</span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> ele </span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">make_tuple</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#066">1</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#066">2</span><span style=3D"c=
olor:#660">))</span><span style=3D"color:#000"> </span><span style=3D"color=
:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 cout </span><span style=3D"colo=
r:#660">&lt;&lt;</span><span style=3D"color:#000"> ele </span><span style=
=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> endl</span><span=
 style=3D"color:#660">;</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
      </div>
    </blockquote>
    <br>
    <br>
    Perhaps:<br>
    <br>
    <br>
    =C2=A0=C2=A0=C2=A0 for constexpr (auto element : std::tuple(1, &quot;a&=
quot;)) {<br>
    =C2=A0 =C2=A0 =C2=A0 =C2=A0 std::cout &lt;&lt; element &lt;&lt; std::en=
dl; <br>
    =C2=A0=C2=A0=C2=A0 }<br>
    <br>
    The rules can then be relaxed that operator++ can return new types;
    the compiler will essentially unroll the loop if that&#39;s the case. <=
br>
    <br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>Iterating through a tuple requires use of minimal amounts
          of metaprogramming, it is easy to write a small helper that
          would automate this for us. =C2=A0But then again, it requires ext=
ra
          work on the programmers part. A language solution seems to be
          more intuitive to me - generalize the range based for loop to
          the stage where it can accept a range of different iterator
          types.=C2=A0</div>
        <div><br>
        </div>
        <div>You might be thinking that such a change cannot be made
          without sacrificing runtime efficiency in the range based for
          loop as it expects the same type for iterators it
          dereferences. =C2=A0What I propose is to not use the <font face=
=3D"courier new, monospace">operator++()</font>=C2=A0method
          (the pre-increment member function) to increment iterators
          when they contain a trait that signals that they are
          heterogenous iterators. =C2=A0Perhaps this could be enabled with
          the help of a <font face=3D"courier new, monospace">preferred_inc=
rement</font><font face=3D"arial, sans-serif">=C2=A0iterator tag, which if =
absent will
            cause the range based for loop to default to prefix
            operator++(), but if present will make the range based for
            loop go with the preferred increment approach (which can
            either be a post-increment and initialization or a reference
            pre-increment). =C2=A0With this small change the tuple class ca=
n
            be modified to support iteration. =C2=A0The iterator for a tupl=
e
            might look something like the following</font></div>
        <div><font face=3D"arial, sans-serif"><br>
          </font></div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#008">template</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#008">typename</span><span style=3D"color:#660">...</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Args</span><span style=3D"c=
olor:#660">&gt;</span><span style=3D"color:#000"><br>
              </span><span style=3D"color:#008">class</span><span style=3D"=
color:#000"> tuple </span><span style=3D"color:#660">{</span><span style=3D=
"color:#000"><br>
              </span><span style=3D"color:#008">public</span><span style=3D=
"color:#660">:</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0<br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The iter=
ator class is
                templated with an integer that denotes which </span><span s=
tyle=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">/</span><fo=
nt color=3D"#000000"><span style=3D"color:#800">/
                  member of the tuple it must fetch from, the tuple type
                  is included</span><span style=3D"color:#000"><br>
                </span></font><span style=3D"color:#000">=C2=A0 =C2=A0 </sp=
an><span style=3D"color:#800">// for
                forwarding reasons</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">template</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</spa=
n><font color=3D"#000088"><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> index</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">typename</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#606">TupleType</span><span =
style=3D"color:#660">&gt;</span></font><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">class</span=
><span style=3D"color:#000"> </span><span style=3D"color:#606">Iterator</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">public</spa=
n><span style=3D"color:#660">:</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// this tells the range based
                for loop to not use the operator++()</span><span style=3D"c=
olor:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// member function to
                increment the iterator, but rather to use the </span><span =
style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// operator++(int) postfix
                increment method</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">using</span><span style=3D"color:#000">
                preferred_increment </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</s=
pan><font color=3D"#000000"><span style=3D"color:#000">post_increment_tag</=
span></font><span style=3D"color:#660">;</span><span style=3D"color:#000"><=
br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// The constructor
                initializes the iterator with a reference to the </span><sp=
an style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// tuple</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">(</span><span style=3D"color:#=
000">tuple</span><span style=3D"color:#660">&lt;</span><span style=3D"color=
:#606">Args</span><span style=3D"color:#660">...&gt;&amp;</span><span style=
=3D"color:#000"> tup_in</span><span style=3D"color:#660">)</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#660">:</span><span style=3D"=
color:#000"> tup</span><span style=3D"color:#660">{</span><span style=3D"co=
lor:#000">tup_in</span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">{}</span><span style=3D"color:=
#000"><br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// The dereference operator
                forwards the tuple and returns the forwarded </span><span s=
tyle=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// result obtained on a call
                to std::get&lt;&gt;</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">decltype</span><span style=3D"color:#660">(</span><span style=3D"color:#=
008">auto</span><span style=3D"color:#660">)</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#008">operator</span><span style=3D"color:#=
660">*()</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">return</span><span style=3D"color:#000"> std</span><span s=
tyle=3D"color:#660">::</span><span style=3D"color:#008">get</span><span sty=
le=3D"color:#080">&lt;index&gt;</span><span style=3D"color:#660">(</span><s=
pan style=3D"color:#000">std</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#000">forward</span><span style=3D"color:#660">&lt;</span>=
<span style=3D"color:#606">T<wbr>upleType</span><span style=3D"color:#660">=
&gt;(</span><span style=3D"color:#008">this</span><span style=3D"color:#660=
">-&gt;</span><span style=3D"color:#000">tup</span><span style=3D"color:#66=
0">));</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#66=
0">}</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// The iterator only defines
                a postfix increment, as is needed for </span><span style=3D=
"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// heterogenosity</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">auto</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>operator</span><span style=3D"color:#660">++(</span><span style=3D"color:#=
008">int</span><span style=3D"color:#660">)</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br=
>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">return</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#606">Iterator</span><span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#000">index </span><span style=3D"color:#660">+</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#066">1</span><span styl=
e=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"=
color:#606">TupleType</span><span style=3D"color:#660">&gt;(</span><span st=
yle=3D"color:#008">this</span><span style=3D"color:#660">-&gt;</span><span =
style=3D"color:#000">tup</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#66=
0">}</span><span style=3D"color:#000"><br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// return a false for
                iterators that are not of the same type</span><span style=
=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">template</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">&lt;</span><font color=3D"#000088"><span style=3D"color:#008">int</spa=
n><span style=3D"color:#000">
                  index_other</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">typename</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#606">TupleType</span=
></font><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><b=
r>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">constexpr</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">bool</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">operator</span><span style=3D"color:#660">!=3D(</span><span style=3D"co=
lor:#008">const</span><span style=3D"color:#000"> </span><font color=3D"#66=
0066"><span style=3D"color:#606">Iterator</span><span style=3D"color:#660">=
&lt;</span><span style=3D"color:#000">index_other</span><span style=3D"colo=
r:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">TupleType</span></font><span style=3D"color:#660">&amp;)</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D=
"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">return</span><span style=3D"color:#000">
                index_other </span><span style=3D"color:#660">!=3D</span><s=
pan style=3D"color:#000"> index</span><span style=3D"color:#660">;</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#66=
0">}</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">};</span><s=
pan style=3D"color:#000"><br>
                <br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The begi=
n() member
                function returns an iterator type that will return</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// lvalue r=
eferences on
                dereferencing</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">begin</span><=
span style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&amp;</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#066">0</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> tuple</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#606">Args</span><span style=3D"color:#660">...&gt;&amp;&gt;{*</span><span =
style=3D"color:#008">this</span><span style=3D"color:#660">};</span><span s=
tyle=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
                =C2=A0 =C2=A0 <br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The begi=
n() member
                function returns an iterator type that will return</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// rvalue r=
eferences on
                dereferencing</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">begin</span><=
span style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// or Iterator&lt;0,
                tuple&lt;Args...&gt;&gt;{*this}; </span><span style=3D"colo=
r:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#066">0</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> tuple</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#606">Args</span><span style=3D"color:#660">...&gt;&amp;&amp;&gt;{*</span><=
span style=3D"color:#008">this</span><span style=3D"color:#660">};</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
                <br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The end =
iterator returns
                an iterator with the sizeof(Args)... as the</span><span sty=
le=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// index, s=
o any iterator
                type that reaches it will compare the same</span><span styl=
e=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The tupl=
e type really
                doesn&#39;t matter here</span><span style=3D"color:#000"><b=
r>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">end</span><sp=
an style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#008">sizeof</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#606">Args</span><span style=3D"color:#660">)...,</span><span style=3D"co=
lor:#000"> tuple</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#606">Args</span><span style=3D"color:#660">...&gt;&gt;{*</span><spa=
n style=3D"color:#008">this</span><span style=3D"color:#660">};</span><span=
 style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
              </span><span style=3D"color:#660">};</span><span style=3D"col=
or:#000"><br>
                <br>
              </span></div>
          </code></div>
        <div><font face=3D"arial, sans-serif"><br>
          </font></div>
        <div><font face=3D"arial, sans-serif">And that would allow the
            range based for loop to increment the iterator with the
            heterogenous postfix iterator increment like so</font></div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#008">for</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#008"=
>auto</span><span style=3D"color:#000"> element
              </span><span style=3D"color:#660">:</span><span style=3D"colo=
r:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"color=
:#000">make_tuple</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#066">1</span><span style=3D"color:#660">,</span><span style=3D"color:=
#000"> </span><span style=3D"color:#080">&quot;some
                string&quot;</span><span style=3D"color:#660">))</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"><br>
                =C2=A0 =C2=A0 cout </span><span style=3D"color:#660">&lt;&l=
t;</span><span style=3D"color:#000"> element
              </span><span style=3D"color:#660">&lt;&lt;</span><span style=
=3D"color:#000"> endl</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br>
              </span><span style=3D"color:#660">}</span><span style=3D"colo=
r:#000"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
        <div>
          <div>Of course making an iterator class for a tuple seems to
            outweigh the benefits, but making such a modification to the
            range based for loop to generalize it further seems to be a
            good idea in my mind as it opens up doors for a whole bunch
            of other things. =C2=A0Like iteration through a range computed =
at
            compile time. =C2=A0The canonical example here could be through
            the fibonacci range</div>
          <div style=3D"border:1px solid rgb(187,187,187);background-color:=
rgb(250,250,250);word-wrap:break-word"><code>
              <div><span style=3D"color:#008">for</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#00=
8">auto</span><span style=3D"color:#000"> val </span><span style=3D"color:#=
660">:</span><span style=3D"color:#000"> std</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#000">fibonacci</span><span style=3D"color=
:#660">{})</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">{</span><span style=3D"color:#000"><br>
                  =C2=A0 =C2=A0 cout </span><span style=3D"color:#660">&lt;=
&lt;</span><span style=3D"color:#000"> val </span><span style=3D"color:#660=
">&lt;&lt;</span><span style=3D"color:#000"> endl</span><span style=3D"colo=
r:#660">;</span><span style=3D"color:#000"><br>
                </span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"><br>
                </span></div>
              <div><span style=3D"color:rgb(102,102,0)"><br>
                </span></div>
            </code></div>
        </div>
        <div><br>
        </div>
        <div>or iterate through a function&#39;s arguments</div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#008">template</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#008">typename</span><span style=3D"color:#660">...</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Args</span><span style=3D"c=
olor:#660">&gt;</span><span style=3D"color:#000"><br>
              </span><span style=3D"color:#008">void</span><span style=3D"c=
olor:#000"> foo</span><span style=3D"color:#660">(</span><span style=3D"col=
or:#606">Args</span><span style=3D"color:#660">&amp;&amp;...</span><span st=
yle=3D"color:#000"> args_in</span><span style=3D"color:#660">)</span><span =
style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> args </span><span style=3D"color:#660">=3D</spa=
n><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span=
><span style=3D"color:#000">forward_as_tuple</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">for<wbr>ward</span><span style=3D"color=
:#660">&lt;</span><span style=3D"color:#606">Args</span><span style=3D"colo=
r:#660">&gt;(</span><span style=3D"color:#000">args_in</span><span style=3D=
"color:#660">)...);</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">for</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span =
style=3D"color:#008">auto</span><span style=3D"color:#660">&amp;&amp;</span=
><span style=3D"color:#000"> arg </span><span style=3D"color:#660">:</span>=
<span style=3D"color:#000"> args</span><span style=3D"color:#660">)</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span =
style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// ...</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
              </span><span style=3D"color:#660">}</span><span style=3D"colo=
r:#000"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
        <div>even something like so will be possible</div>
        <div>
          <div style=3D"background-color:rgb(250,250,250);border:1px solid =
rgb(187,187,187);word-wrap:break-word"><code>
              <div><span style=3D"color:#800">// compile time iteration
                  through a range of integers</span><span style=3D"color:#0=
00"><br>
                </span><span style=3D"color:#008">for</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">(</span><font color=3D"#0000=
88"><span style=3D"color:#008">auto</span><span style=3D"color:#000">
                    index </span><span style=3D"color:#660">:</span><span s=
tyle=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span st=
yle=3D"color:#000">make_integer_sequence</span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#008">int</span><span style=3D"color:#660"><=
wbr>,</span><span style=3D"color:#066">10</span><span style=3D"color:#660">=
&gt;{})</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>{</span><span style=3D"color:#000"><br>
                    =C2=A0 =C2=A0 cout </span><span style=3D"color:#660">&l=
t;&lt;</span><span style=3D"color:#000"> std</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#008">get</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#008">static_cast</span><span style=3D"col=
or:#080">&lt;int&gt;</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">inde<wbr>x</span><span style=3D"color:#660">)&gt;(</span><s=
pan style=3D"color:#000">some_tuple</span><span style=3D"color:#660">)</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;&lt;</s=
pan><span style=3D"color:#000">
                    endl</span><span style=3D"color:#660">;</span><span sty=
le=3D"color:#000"><br>
                  </span><span style=3D"color:#660">}</span></font></div>
            </code></div>
        </div>
        <div><br>
        </div>
        <div>Apologies for the mistakes in the code, I didn&#39;t actually
          compile any of it, it is just a vision of what I hope might
          come to pass if people like this idea.=C2=A0</div>
      </div>
      -- <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 email to <a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"OUVYCOj0AwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#=
39;;return true;">std-proposal...@<wbr>isocpp.org</a>.<br>
      To post to this group, send email to <a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"OUVYCOj0AwAJ" rel=3D"nofollow" onmouse=
down=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;javascript:&#39;;return true;">std-pr...@isocpp.org</a>.<br>
      To view this discussion on the web visit <a href=3D"https://groups.go=
ogle.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef=
5bf96%40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_b=
lank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://groups.googl=
e.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf=
96%40isocpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/ms=
gid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org?utm_med=
ium\x3demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.goog=
le.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/05e0675e-4c5d-4ad4-<wbr=
>a1e4-4cf10ef5bf96%40isocpp.org</a><wbr>.<br>
    </blockquote>
    <p><br>
    </p>
  </div>

</blockquote></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/3f5d11c8-3d0f-41ad-91eb-328186e981ad%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3f5d11c8-3d0f-41ad-91eb-328186e981ad=
%40isocpp.org</a>.<br />

------=_Part_3162_1146729875.1495523250059--

------=_Part_3161_829625352.1495523250057--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 23 May 2017 07:10:46 -0700 (PDT)
Raw View
------=_Part_3426_1639633547.1495548646303
Content-Type: multipart/alternative;
 boundary="----=_Part_3427_1765226116.1495548646303"

------=_Part_3427_1765226116.1495548646303
Content-Type: text/plain; charset="UTF-8"



On Tuesday, May 23, 2017 at 12:10:40 AM UTC-4, rmn...@gmail.com wrote:
>
> C++17 has a new feature that would improve the functionality of range
> based for loops to work with begin and end iterators that are not of the
> same type as proposed by Eric Niebler here
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html.
>  This is a great feature, as it generalizes the range based for loop to fit
> scenarios that would otherwise not be possible, essentially making it more
> adaptable.
>
> But something like the following is still not possible using the range
> based for loop, since the dereferenced iterators must be the same type, and
> therefore cannot contain any compile time information
>     for (auto ele : std::make_tuple(1, 2)) {
>         cout << ele << endl;
>     }
>
> Iterating through a tuple requires use of minimal amounts of
> metaprogramming, it is easy to write a small helper that would automate
> this for us.
>

No, it's not. It's not even *possible* unless every element of the tuple is
of the same type (or is implicitly convertible to the same type). `auto
ele` cannot change its type; it must be of the begin iterator's value_type.
Which is a static property that cannot change based on where the iterator
is.

I much prefer we just have this <http://wg21.link/P0535>. It will allow
plenty of ways to "iterate" over elements of a tuple.

But then again, it requires extra work on the programmers part. A language
> solution seems to be more intuitive to me - generalize the range based for
> loop to the stage where it can accept a range of different iterator types.
>

No.

--
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/807834e9-6626-406f-bfff-a44914fa4a15%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Tuesday, May 23, 2017 at 12:10:40 AM UTC-4, rmn=
....@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">C++17 has a new feature that would improve the functionality of ra=
nge based for loops to work with begin and end iterators that are not of th=
e same type as proposed by Eric Niebler here <a href=3D"http://www.open-std=
..org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html" target=3D"_blank" rel=3D=
"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\x3dh=
ttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2F=
p0184r0.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHsm16utECLKaIF1azvSKcF=
VZwR1g&#39;;return true;" onclick=3D"this.href=3D&#39;http://www.google.com=
/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpaper=
s%2F2016%2Fp0184r0.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHsm16utECLK=
aIF1azvSKcFVZwR1g&#39;;return true;">http://www.open-std.org/jtc1/<wbr>sc22=
/wg21/docs/papers/2016/<wbr>p0184r0.html</a>. =C2=A0This is a great feature=
, as it generalizes the range based for loop to fit scenarios that would ot=
herwise not be possible, essentially making it more adaptable. =C2=A0<div><=
br></div><div>But something like the following is still not possible using =
the range based for loop, since the dereferenced iterators must be the same=
 type, and therefore cannot contain any compile time information</div><div =
style=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187,187=
);word-wrap:break-word"><code><div><span style=3D"color:#000">=C2=A0 =C2=A0=
 </span><span style=3D"color:#008">for</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">(</span><span style=3D"color:#008">auto</sp=
an><span style=3D"color:#000"> ele </span><span style=3D"color:#660">:</spa=
n><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span=
><span style=3D"color:#000">make_tuple</span><span style=3D"color:#660">(</=
span><span style=3D"color:#066">1</span><span style=3D"color:#660">,</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#066">2</span><span=
 style=3D"color:#660">))</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 cout </span><span style=3D"color:#660">&lt;&lt;</span><span styl=
e=3D"color:#000"> ele </span><span style=3D"color:#660">&lt;&lt;</span><spa=
n style=3D"color:#000"> endl</span><span style=3D"color:#660">;</span><span=
 style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}=
</span><span style=3D"color:#000"><br></span></div></code></div><div><br></=
div></div></blockquote><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"><div>Iterating through a tuple requires use of minim=
al amounts of metaprogramming, it is easy to write a small helper that woul=
d automate this for us.</div></div></blockquote><div><br>No, it&#39;s not. =
It&#39;s not even <i>possible</i> unless every element of the tuple is of t=
he same type (or is implicitly convertible to the same type). `auto ele` ca=
nnot change its type; it must be of the begin iterator&#39;s value_type. Wh=
ich is a static property that cannot change based on where the iterator is.=
<br><br>I much prefer we just <a href=3D"http://wg21.link/P0535">have this<=
/a>. It will allow plenty of ways to &quot;iterate&quot; over elements of a=
 tuple.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div>But then again, it requires extra work on the programmers par=
t. A language solution seems to be more intuitive to me - generalize the ra=
nge based for loop to the stage where it can accept a range of different it=
erator types.</div></div></blockquote><div><br>No.</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/807834e9-6626-406f-bfff-a44914fa4a15%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/807834e9-6626-406f-bfff-a44914fa4a15=
%40isocpp.org</a>.<br />

------=_Part_3427_1765226116.1495548646303--

------=_Part_3426_1639633547.1495548646303--

.


Author: rmn100@gmail.com
Date: Tue, 23 May 2017 07:37:28 -0700 (PDT)
Raw View
------=_Part_3423_930849892.1495550248578
Content-Type: multipart/alternative;
 boundary="----=_Part_3424_1204697159.1495550248581"

------=_Part_3424_1204697159.1495550248581
Content-Type: text/plain; charset="UTF-8"

@AviKivity

Firstly rethinking the design decision to have an iterator representing a
compile time range, it seems wrong and might not even work.  Rather a
design based on std::get<> and std::tuple_size<> seems better and easier

Regarding the for constexpr I feel like that would defeat the main purpose
of such a change to the range based for loop - code reusability for compile
time and and runtime ranges.  What I had in mind was the ability to do
something like this

template <typename Range>
void do_something_with_range(Range&& range) {
    for (auto&& element : range) {
        // do something with range
    }
}

Now this function can be invoked as

// with the new rules for type deduction in constructors
do_something_with_range(std::tuple{1, "something", 3.14159265});
do_something_with_range(std::vector{1, 2, 3, 4});

Now one function can be used in cases where the user wants to pass a
compile time range as well as a runtime range.  More importantly, you can *reuse
code*!

template <typename... Args>
void do_something_with_range(Args&&... args) {
    auto t = std::forward_as_tuple(std::forward<Args>(args)...);
    do_something_with_range_impl(t);
}

template <typename Vector>
void do_something_with_range(Vector&& vec) {
    do_something_with_range_impl(std::forward<Vector>(vec));
}

The change would not be breaking since no iterator class includes a tag of
the type that is proposed, and most standard libraries do not include a tag
by that name, so the change would look something like the following

*Until C++17*
{
    auto && __range = range_expression ;
    for (auto __begin = begin_expr, __end = end_expr;
            __begin != __end; ++__begin) {
        range_declaration = *__begin;
        loop_statement
    }
}

*Since C++17*
{
    auto && __range = range_expression ;
    auto __begin = begin_expr ;
    auto __end = end_expr ;
    for ( ; __begin != __end; ++__begin) {
        range_declaration = *__begin;
        loop_statement
    }
}

*Since C++20 *(Thinking about it now, I feel like a better choice is to
allow iteration over a range that has std::get<> and std::tuple_size<>
defined for it)
auto && __range = range_expression ;
constexpr if (is_std_get_defined_for(__range)) {
    // unrolled loop from 0 to
    // std::tuple_size_v<std::decay_t<decltype(__range)>> follows
    {
        range_declaration = std::get<0>(__range);
        loop_statement
    }
    {
        range_declaration = std::get<0>(__range);
        loop_statement
    }
    ...
} constexpr else {
    auto __begin = begin_expr ;
    auto __end = end_expr ;
    for ( ; __begin != __end; ++__begin) {
        range_declaration = *__begin;
        loop_statement
    }
}

On Tuesday, 23 May 2017 02:30:12 UTC-4, Avi Kivity wrote:
>
> On 05/23/2017 07:10 AM, rmn...@gmail.com <javascript:> wrote:
>
> C++17 has a new feature that would improve the functionality of range
> based for loops to work with begin and end iterators that are not of the
> same type as proposed by Eric Niebler here
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html.
>  This is a great feature, as it generalizes the range based for loop to fit
> scenarios that would otherwise not be possible, essentially making it more
> adaptable.
>
> But something like the following is still not possible using the range
> based for loop, since the dereferenced iterators must be the same type, and
> therefore cannot contain any compile time information
>     for (auto ele : std::make_tuple(1, 2)) {
>         cout << ele << endl;
>     }
>
>
>
> Perhaps:
>
>     for constexpr (auto element : std::tuple(1, "a")) {
>         std::cout << element << std::endl;
>     }
>
> The rules can then be relaxed that operator++ can return new types; the
> compiler will essentially unroll the loop if that's the case.
>
> Iterating through a tuple requires use of minimal amounts of
> metaprogramming, it is easy to write a small helper that would automate
> this for us.  But then again, it requires extra work on the programmers
> part. A language solution seems to be more intuitive to me - generalize the
> range based for loop to the stage where it can accept a range of different
> iterator types.
>
> You might be thinking that such a change cannot be made without
> sacrificing runtime efficiency in the range based for loop as it expects
> the same type for iterators it dereferences.  What I propose is to not use
> the operator++() method (the pre-increment member function) to increment
> iterators when they contain a trait that signals that they are heterogenous
> iterators.  Perhaps this could be enabled with the help of a
> preferred_increment iterator tag, which if absent will cause the range
> based for loop to default to prefix operator++(), but if present will make
> the range based for loop go with the preferred increment approach (which
> can either be a post-increment and initialization or a reference
> pre-increment).  With this small change the tuple class can be modified to
> support iteration.  The iterator for a tuple might look something like the
> following
>
> template <typename... Args>
> class tuple {
> public:
>
>     // The iterator class is templated with an integer that denotes which
>     // member of the tuple it must fetch from, the tuple type is included
>     // for forwarding reasons
>     template <int index, typename TupleType>
>     class Iterator {
>     public:
>         // this tells the range based for loop to not use the operator++()
>         // member function to increment the iterator, but rather to use
> the
>         // operator++(int) postfix increment method
>         using preferred_increment = std::post_increment_tag;
>
>         // The constructor initializes the iterator with a reference to
> the
>         // tuple
>         Iterator(tuple<Args...>& tup_in) : tup{tup_in} {}
>
>         // The dereference operator forwards the tuple and returns the
> forwarded
>         // result obtained on a call to std::get<>
>         decltype(auto) operator*() {
>             return std::get<index>(std::forward<TupleType>(this->tup));
>         }
>
>         // The iterator only defines a postfix increment, as is needed
> for
>         // heterogenosity
>         auto operator++(int) {
>             return Iterator<index + 1, TupleType>(this->tup);
>         }
>
>         // return a false for iterators that are not of the same type
>         template <int index_other, typename TupleType>
>         constexpr bool operator!=(const Iterator<index_other, TupleType&)
> {
>             return index_other != index;
>         }
>     };
>
>     // The begin() member function returns an iterator type that will
> return
>     // lvalue references on dereferencing
>     auto begin() & {
>         return Iterator<0, tuple<Args...>&>{*this};
>     }
>
>     // The begin() member function returns an iterator type that will
> return
>     // rvalue references on dereferencing
>     auto begin() && {
>         // or Iterator<0, tuple<Args...>>{*this};
>         return Iterator<0, tuple<Args...>&&>{*this};
>     }
>
>     // The end iterator returns an iterator with the sizeof(Args)... as
> the
>     // index, so any iterator type that reaches it will compare the same
>     // The tuple type really doesn't matter here
>     auto end() {
>         return Iterator<sizeof(Args)..., tuple<Args...>>{*this};
>     }
> };
>
>
> And that would allow the range based for loop to increment the iterator
> with the heterogenous postfix iterator increment like so
> for (auto element : std::make_tuple(1, "some string")) {
>     cout << element << endl;
> }
>
> Of course making an iterator class for a tuple seems to outweigh the
> benefits, but making such a modification to the range based for loop to
> generalize it further seems to be a good idea in my mind as it opens up
> doors for a whole bunch of other things.  Like iteration through a range
> computed at compile time.  The canonical example here could be through the
> fibonacci range
> for (auto val : std::fibonacci{}) {
>     cout << val << endl;
> }
>
>
> or iterate through a function's arguments
> template <typename... Args>
> void foo(Args&&... args_in) {
>     auto args = std::forward_as_tuple(std::forward<Args>(args_in)...);
>     for (auto&& arg : args) {
>         // ...
>     }
> }
>
> even something like so will be possible
> // compile time iteration through a range of integers
> for (auto index : std::make_integer_sequence<int,10>{}) {
>     cout << std::get<static_cast<int>(index)>(some_tuple) << endl;
> }
>
> Apologies for the mistakes in the code, I didn't actually compile any of
> it, it is just a vision of what I hope might come to pass if people like
> this idea.
> --
> 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-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
>
>

--
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/7bf0527f-8001-49bb-8b04-2616f992486c%40isocpp.org.

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

<div dir=3D"ltr">@AviKivity<div><br></div><div>Firstly rethinking the desig=
n decision to have an iterator representing a compile time range, it seems =
wrong and might not even work. =C2=A0Rather a design based on <font face=3D=
"courier new, monospace">std::get&lt;&gt;</font> and <font face=3D"courier =
new, monospace">std::tuple_size&lt;&gt;</font> seems better and easier</div=
><div><br></div><div>Regarding the <font face=3D"courier new, monospace">fo=
r constexpr</font> I feel like that would defeat the main purpose of such a=
 change to the range based for loop - code reusability for compile time and=
 and runtime ranges. =C2=A0What I had in mind was the ability to do somethi=
ng like this<br></div><div><br></div><div class=3D"prettyprint" style=3D"ba=
ckground-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); w=
ord-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyp=
rint"><span style=3D"color: #008;" class=3D"styled-by-prettify">template</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Range</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> do_something_with_range</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"=
styled-by-prettify">Range</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> range</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">for</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> element </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> range</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"s=
tyled-by-prettify">// do something with range</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span></div></code></div><div><br></div><div>Now th=
is function can be invoked as=C2=A0</div><div><br></div><div class=3D"prett=
yprint" style=3D"background-color: rgb(250, 250, 250); border: 1px solid rg=
b(187, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><span style=3D"color: #800;" class=3D"styled-by-pr=
ettify">// with the new rules for type deduction in constructors</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>do_something_with=
_range</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">tuple</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #06=
6;" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">&quot;something&quot;</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">3=
..14159265</span><span style=3D"color: #660;" class=3D"styled-by-prettify">}=
);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>do_s=
omething_with_range</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">vector</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"=
styled-by-prettify">2</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">3</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">4</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">});</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span></div></code></div><div><br></div><div>=
Now one function can be used in cases where the user wants to pass a compil=
e time range as well as a runtime range. =C2=A0More importantly, you can <b=
>reuse code</b>!=C2=A0</div><div><br></div><div class=3D"prettyprint" style=
=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 1=
87); word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">templ=
ate</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
606;" class=3D"styled-by-prettify">Args</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> do_something_with_range</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">Args</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&amp;&amp;...</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> args</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> t </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">forward_as_tuple</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">forward</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-pre=
ttify">Args</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&gt;(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">args=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)...);</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 do_something_with_range_impl</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">t</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">template</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;"=
 class=3D"styled-by-prettify">Vector</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> do_something_with_range</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Vector</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> vec</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 do_s=
omething_with_range_impl</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">forward</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><s=
pan style=3D"color: #606;" class=3D"styled-by-prettify">Vector</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">vec</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">));</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">}</span></div></code></div><div><br>The change w=
ould not be breaking since no iterator class includes a tag of the type tha=
t is proposed, and most standard libraries do not include a tag by that nam=
e, so the change would look something like the following</div><div><br></di=
v><div><b>Until C++17</b></div><div><div class=3D"prettyprint" style=3D"bac=
kground-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); wo=
rd-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> __range </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> range_expression </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> <br>=C2=A0 =C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">for</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> __begin </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> begin_expr</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> __end </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> end_ex=
pr</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> <br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 __begin </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">!=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> __end</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">++</span><span style=3D"color: #000;" class=3D"styled-by-prettify">__begi=
n</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> <br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 ran=
ge_declaration </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">__begin</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> <br>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
 loop_statement <br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> <br></span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">}</span></div></code></div></div><div><br></div><div><b>Since C++=
17</b></div><div class=3D"prettyprint" style=3D"background-color: rgb(250, =
250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> __range </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> range_expression </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> <br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> __begin </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> begin_expr </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> __end </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> end=
_expr </span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">for=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> __begin </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">!=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> __end</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">++</span><span style=3D"color: #000;" class=3D"styled-by-prettify">__begi=
n</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> <br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 ran=
ge_declaration </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">__begin</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> <br>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
 loop_statement <br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> <br></span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> <br></span></div></code></div><div><br><b>Since C++20 </b>(Thinking about=
 it now, I feel like a better choice is to allow iteration over a range tha=
t has std::get&lt;&gt; and std::tuple_size&lt;&gt; defined for it)</div><di=
v><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187);=
 background-color: rgb(250, 250, 250); word-wrap: break-word;"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> __range </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> range_expression </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> <br></span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>constexpr</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">if</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">is_std</span><font color=3D"#666600=
"><span style=3D"color: #000;" class=3D"styled-by-prettify">_</span></font>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">get_defined_for</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">__range</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">))</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">// unrolled loop from 0 to </span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">// std::tuple_siz=
e_v&lt;std::decay_t&lt;decltype(__range)&gt;&gt; follows</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 range_declaration </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><font color=3D"#666600"><span style=3D"color: #000;" class=3D"=
styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">get</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&l=
t;</span><span style=3D"color: #066;" class=3D"styled-by-prettify">0</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">__range</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span></font><span style=3D"=
color: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 =C2=A0 =C2=A0 loop=
_statement<br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 range_declaration </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><font color=3D"#666600"><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">get</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #066;" c=
lass=3D"styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&gt;(</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify">__range</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span></font><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">=C2=A0 =C2=A0 =C2=A0 =C2=A0 loop_statement<br>=C2=A0 =C2=A0 </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">...</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">constexpr</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">else</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> __be=
gin </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> begin_expr <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> __end </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> end_expr </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">for</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> __begin </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">!=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
__end</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">++</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">__begin</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> <br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 range_declaration </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">__begin</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> <br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 loop_statement <br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br></s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span></div></code><=
/div></div><div><br></div><div>On Tuesday, 23 May 2017 02:30:12 UTC-4, Avi =
Kivity  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div>On 05/23/2017 07:10 AM,
      <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"OU=
VYCOj0AwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#3=
9;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;"=
>rmn...@gmail.com</a> wrote:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">C++17 has a new feature that would improve the
        functionality of range based for loops to work with begin and
        end iterators that are not of the same type as proposed by Eric
        Niebler here
        <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/=
p0184r0.html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=
=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1=
%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0184r0.html\x26sa\x3dD\x26sntz\x3d=
1\x26usg\x3dAFQjCNHsm16utECLKaIF1azvSKcFVZwR1g&#39;;return true;" onclick=
=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-s=
td.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0184r0.html\x26sa\x3d=
D\x26sntz\x3d1\x26usg\x3dAFQjCNHsm16utECLKaIF1azvSKcFVZwR1g&#39;;return tru=
e;">http://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2016/<wbr>p0184=
r0.html</a>.
        =C2=A0This is a great feature, as it generalizes the range based fo=
r
        loop to fit scenarios that would otherwise not be possible,
        essentially making it more adaptable. =C2=A0
        <div><br>
        </div>
        <div>But something like the following is still not possible
          using the range based for loop, since the dereferenced
          iterators must be the same type, and therefore cannot contain
          any compile time information</div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#000">=C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">for</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">(</span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> ele </span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">make_tuple</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#066">1</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#066">2</span><span style=3D"c=
olor:#660">))</span><span style=3D"color:#000"> </span><span style=3D"color=
:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 cout </span><span style=3D"colo=
r:#660">&lt;&lt;</span><span style=3D"color:#000"> ele </span><span style=
=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> endl</span><span=
 style=3D"color:#660">;</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
      </div>
    </blockquote>
    <br>
    <br>
    Perhaps:<br>
    <br></div></blockquote><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v text=3D"#000000" bgcolor=3D"#FFFFFF">
    =C2=A0=C2=A0=C2=A0 for constexpr (auto element : std::tuple(1, &quot;a&=
quot;)) {<br>
    =C2=A0 =C2=A0 =C2=A0 =C2=A0 std::cout &lt;&lt; element &lt;&lt; std::en=
dl; <br>
    =C2=A0=C2=A0=C2=A0 }<br>
    <br>
    The rules can then be relaxed that operator++ can return new types;
    the compiler will essentially unroll the loop if that&#39;s the case. <=
br>
    <br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>Iterating through a tuple requires use of minimal amounts
          of metaprogramming, it is easy to write a small helper that
          would automate this for us. =C2=A0But then again, it requires ext=
ra
          work on the programmers part. A language solution seems to be
          more intuitive to me - generalize the range based for loop to
          the stage where it can accept a range of different iterator
          types.=C2=A0</div>
        <div><br>
        </div>
        <div>You might be thinking that such a change cannot be made
          without sacrificing runtime efficiency in the range based for
          loop as it expects the same type for iterators it
          dereferences. =C2=A0What I propose is to not use the <font face=
=3D"courier new, monospace">operator++()</font>=C2=A0method
          (the pre-increment member function) to increment iterators
          when they contain a trait that signals that they are
          heterogenous iterators. =C2=A0Perhaps this could be enabled with
          the help of a <font face=3D"courier new, monospace">preferred_inc=
rement</font><font face=3D"arial, sans-serif">=C2=A0iterator tag, which if =
absent will
            cause the range based for loop to default to prefix
            operator++(), but if present will make the range based for
            loop go with the preferred increment approach (which can
            either be a post-increment and initialization or a reference
            pre-increment). =C2=A0With this small change the tuple class ca=
n
            be modified to support iteration. =C2=A0The iterator for a tupl=
e
            might look something like the following</font></div>
        <div><font face=3D"arial, sans-serif"><br>
          </font></div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#008">template</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#008">typename</span><span style=3D"color:#660">...</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Args</span><span style=3D"c=
olor:#660">&gt;</span><span style=3D"color:#000"><br>
              </span><span style=3D"color:#008">class</span><span style=3D"=
color:#000"> tuple </span><span style=3D"color:#660">{</span><span style=3D=
"color:#000"><br>
              </span><span style=3D"color:#008">public</span><span style=3D=
"color:#660">:</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0<br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The iter=
ator class is
                templated with an integer that denotes which </span><span s=
tyle=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">/</span><fo=
nt color=3D"#000000"><span style=3D"color:#800">/
                  member of the tuple it must fetch from, the tuple type
                  is included</span><span style=3D"color:#000"><br>
                </span></font><span style=3D"color:#000">=C2=A0 =C2=A0 </sp=
an><span style=3D"color:#800">// for
                forwarding reasons</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">template</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</spa=
n><font color=3D"#000088"><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> index</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">typename</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#606">TupleType</span><span =
style=3D"color:#660">&gt;</span></font><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">class</span=
><span style=3D"color:#000"> </span><span style=3D"color:#606">Iterator</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">public</spa=
n><span style=3D"color:#660">:</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// this tells the range based
                for loop to not use the operator++()</span><span style=3D"c=
olor:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// member function to
                increment the iterator, but rather to use the </span><span =
style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// operator++(int) postfix
                increment method</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">using</span><span style=3D"color:#000">
                preferred_increment </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</s=
pan><font color=3D"#000000"><span style=3D"color:#000">post_increment_tag</=
span></font><span style=3D"color:#660">;</span><span style=3D"color:#000"><=
br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// The constructor
                initializes the iterator with a reference to the </span><sp=
an style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// tuple</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">(</span><span style=3D"color:#=
000">tuple</span><span style=3D"color:#660">&lt;</span><span style=3D"color=
:#606">Args</span><span style=3D"color:#660">...&gt;&amp;</span><span style=
=3D"color:#000"> tup_in</span><span style=3D"color:#660">)</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#660">:</span><span style=3D"=
color:#000"> tup</span><span style=3D"color:#660">{</span><span style=3D"co=
lor:#000">tup_in</span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">{}</span><span style=3D"color:=
#000"><br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// The dereference operator
                forwards the tuple and returns the forwarded </span><span s=
tyle=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// result obtained on a call
                to std::get&lt;&gt;</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">decltype</span><span style=3D"color:#660">(</span><span style=3D"color:#=
008">auto</span><span style=3D"color:#660">)</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#008">operator</span><span style=3D"color:#=
660">*()</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">return</span><span style=3D"color:#000"> std</span><span s=
tyle=3D"color:#660">::</span><span style=3D"color:#008">get</span><span sty=
le=3D"color:#080">&lt;index&gt;</span><span style=3D"color:#660">(</span><s=
pan style=3D"color:#000">std</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#000">forward</span><span style=3D"color:#660">&lt;</span>=
<span style=3D"color:#606">T<wbr>upleType</span><span style=3D"color:#660">=
&gt;(</span><span style=3D"color:#008">this</span><span style=3D"color:#660=
">-&gt;</span><span style=3D"color:#000">tup</span><span style=3D"color:#66=
0">));</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#66=
0">}</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// The iterator only defines
                a postfix increment, as is needed for </span><span style=3D=
"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// heterogenosity</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">auto</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>operator</span><span style=3D"color:#660">++(</span><span style=3D"color:#=
008">int</span><span style=3D"color:#660">)</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br=
>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">return</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#606">Iterator</span><span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#000">index </span><span style=3D"color:#660">+</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#066">1</span><span styl=
e=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"=
color:#606">TupleType</span><span style=3D"color:#660">&gt;(</span><span st=
yle=3D"color:#008">this</span><span style=3D"color:#660">-&gt;</span><span =
style=3D"color:#000">tup</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#66=
0">}</span><span style=3D"color:#000"><br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// return a false for
                iterators that are not of the same type</span><span style=
=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">template</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">&lt;</span><font color=3D"#000088"><span style=3D"color:#008">int</spa=
n><span style=3D"color:#000">
                  index_other</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">typename</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#606">TupleType</span=
></font><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><b=
r>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">constexpr</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">bool</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">operator</span><span style=3D"color:#660">!=3D(</span><span style=3D"co=
lor:#008">const</span><span style=3D"color:#000"> </span><font color=3D"#66=
0066"><span style=3D"color:#606">Iterator</span><span style=3D"color:#660">=
&lt;</span><span style=3D"color:#000">index_other</span><span style=3D"colo=
r:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">TupleType</span></font><span style=3D"color:#660">&amp;)</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D=
"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">return</span><span style=3D"color:#000">
                index_other </span><span style=3D"color:#660">!=3D</span><s=
pan style=3D"color:#000"> index</span><span style=3D"color:#660">;</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#66=
0">}</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">};</span><s=
pan style=3D"color:#000"><br>
                <br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The begi=
n() member
                function returns an iterator type that will return</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// lvalue r=
eferences on
                dereferencing</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">begin</span><=
span style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&amp;</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#066">0</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> tuple</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#606">Args</span><span style=3D"color:#660">...&gt;&amp;&gt;{*</span><span =
style=3D"color:#008">this</span><span style=3D"color:#660">};</span><span s=
tyle=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
                =C2=A0 =C2=A0 <br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The begi=
n() member
                function returns an iterator type that will return</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// rvalue r=
eferences on
                dereferencing</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">begin</span><=
span style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// or Iterator&lt;0,
                tuple&lt;Args...&gt;&gt;{*this}; </span><span style=3D"colo=
r:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#066">0</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> tuple</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#606">Args</span><span style=3D"color:#660">...&gt;&amp;&amp;&gt;{*</span><=
span style=3D"color:#008">this</span><span style=3D"color:#660">};</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
                <br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The end =
iterator returns
                an iterator with the sizeof(Args)... as the</span><span sty=
le=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// index, s=
o any iterator
                type that reaches it will compare the same</span><span styl=
e=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The tupl=
e type really
                doesn&#39;t matter here</span><span style=3D"color:#000"><b=
r>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">end</span><sp=
an style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#008">sizeof</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#606">Args</span><span style=3D"color:#660">)...,</span><span style=3D"co=
lor:#000"> tuple</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#606">Args</span><span style=3D"color:#660">...&gt;&gt;{*</span><spa=
n style=3D"color:#008">this</span><span style=3D"color:#660">};</span><span=
 style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
              </span><span style=3D"color:#660">};</span><span style=3D"col=
or:#000"><br>
                <br>
              </span></div>
          </code></div>
        <div><font face=3D"arial, sans-serif"><br>
          </font></div>
        <div><font face=3D"arial, sans-serif">And that would allow the
            range based for loop to increment the iterator with the
            heterogenous postfix iterator increment like so</font></div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#008">for</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#008"=
>auto</span><span style=3D"color:#000"> element
              </span><span style=3D"color:#660">:</span><span style=3D"colo=
r:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"color=
:#000">make_tuple</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#066">1</span><span style=3D"color:#660">,</span><span style=3D"color:=
#000"> </span><span style=3D"color:#080">&quot;some
                string&quot;</span><span style=3D"color:#660">))</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"><br>
                =C2=A0 =C2=A0 cout </span><span style=3D"color:#660">&lt;&l=
t;</span><span style=3D"color:#000"> element
              </span><span style=3D"color:#660">&lt;&lt;</span><span style=
=3D"color:#000"> endl</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br>
              </span><span style=3D"color:#660">}</span><span style=3D"colo=
r:#000"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
        <div>
          <div>Of course making an iterator class for a tuple seems to
            outweigh the benefits, but making such a modification to the
            range based for loop to generalize it further seems to be a
            good idea in my mind as it opens up doors for a whole bunch
            of other things. =C2=A0Like iteration through a range computed =
at
            compile time. =C2=A0The canonical example here could be through
            the fibonacci range</div>
          <div style=3D"border:1px solid rgb(187,187,187);background-color:=
rgb(250,250,250);word-wrap:break-word"><code>
              <div><span style=3D"color:#008">for</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#00=
8">auto</span><span style=3D"color:#000"> val </span><span style=3D"color:#=
660">:</span><span style=3D"color:#000"> std</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#000">fibonacci</span><span style=3D"color=
:#660">{})</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">{</span><span style=3D"color:#000"><br>
                  =C2=A0 =C2=A0 cout </span><span style=3D"color:#660">&lt;=
&lt;</span><span style=3D"color:#000"> val </span><span style=3D"color:#660=
">&lt;&lt;</span><span style=3D"color:#000"> endl</span><span style=3D"colo=
r:#660">;</span><span style=3D"color:#000"><br>
                </span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"><br>
                </span></div>
              <div><span style=3D"color:rgb(102,102,0)"><br>
                </span></div>
            </code></div>
        </div>
        <div><br>
        </div>
        <div>or iterate through a function&#39;s arguments</div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#008">template</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#008">typename</span><span style=3D"color:#660">...</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Args</span><span style=3D"c=
olor:#660">&gt;</span><span style=3D"color:#000"><br>
              </span><span style=3D"color:#008">void</span><span style=3D"c=
olor:#000"> foo</span><span style=3D"color:#660">(</span><span style=3D"col=
or:#606">Args</span><span style=3D"color:#660">&amp;&amp;...</span><span st=
yle=3D"color:#000"> args_in</span><span style=3D"color:#660">)</span><span =
style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> args </span><span style=3D"color:#660">=3D</spa=
n><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span=
><span style=3D"color:#000">forward_as_tuple</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">for<wbr>ward</span><span style=3D"color=
:#660">&lt;</span><span style=3D"color:#606">Args</span><span style=3D"colo=
r:#660">&gt;(</span><span style=3D"color:#000">args_in</span><span style=3D=
"color:#660">)...);</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">for</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span =
style=3D"color:#008">auto</span><span style=3D"color:#660">&amp;&amp;</span=
><span style=3D"color:#000"> arg </span><span style=3D"color:#660">:</span>=
<span style=3D"color:#000"> args</span><span style=3D"color:#660">)</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span =
style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// ...</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
              </span><span style=3D"color:#660">}</span><span style=3D"colo=
r:#000"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
        <div>even something like so will be possible</div>
        <div>
          <div style=3D"background-color:rgb(250,250,250);border:1px solid =
rgb(187,187,187);word-wrap:break-word"><code>
              <div><span style=3D"color:#800">// compile time iteration
                  through a range of integers</span><span style=3D"color:#0=
00"><br>
                </span><span style=3D"color:#008">for</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">(</span><font color=3D"#0000=
88"><span style=3D"color:#008">auto</span><span style=3D"color:#000">
                    index </span><span style=3D"color:#660">:</span><span s=
tyle=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span st=
yle=3D"color:#000">make_integer_sequence</span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#008">int</span><span style=3D"color:#660"><=
wbr>,</span><span style=3D"color:#066">10</span><span style=3D"color:#660">=
&gt;{})</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>{</span><span style=3D"color:#000"><br>
                    =C2=A0 =C2=A0 cout </span><span style=3D"color:#660">&l=
t;&lt;</span><span style=3D"color:#000"> std</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#008">get</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#008">static_cast</span><span style=3D"col=
or:#080">&lt;int&gt;</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">inde<wbr>x</span><span style=3D"color:#660">)&gt;(</span><s=
pan style=3D"color:#000">some_tuple</span><span style=3D"color:#660">)</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;&lt;</s=
pan><span style=3D"color:#000">
                    endl</span><span style=3D"color:#660">;</span><span sty=
le=3D"color:#000"><br>
                  </span><span style=3D"color:#660">}</span></font></div>
            </code></div>
        </div>
        <div><br>
        </div>
        <div>Apologies for the mistakes in the code, I didn&#39;t actually
          compile any of it, it is just a vision of what I hope might
          come to pass if people like this idea.=C2=A0</div>
      </div>
      -- <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 email to <a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"OUVYCOj0AwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#=
39;;return true;">std-proposal...@<wbr>isocpp.org</a>.<br>
      To post to this group, send email to <a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"OUVYCOj0AwAJ" rel=3D"nofollow" onmouse=
down=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;javascript:&#39;;return true;">std-pr...@isocpp.org</a>.<br>
      To view this discussion on the web visit <a href=3D"https://groups.go=
ogle.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef=
5bf96%40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_b=
lank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://groups.googl=
e.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf=
96%40isocpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/ms=
gid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org?utm_med=
ium\x3demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.goog=
le.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/05e0675e-4c5d-4ad4-<wbr=
>a1e4-4cf10ef5bf96%40isocpp.org</a><wbr>.<br>
    </blockquote>
    <p><br>
    </p>
  </div>

</blockquote></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/7bf0527f-8001-49bb-8b04-2616f992486c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7bf0527f-8001-49bb-8b04-2616f992486c=
%40isocpp.org</a>.<br />

------=_Part_3424_1204697159.1495550248581--

------=_Part_3423_930849892.1495550248578--

.


Author: rmn100@gmail.com
Date: Tue, 23 May 2017 07:40:10 -0700 (PDT)
Raw View
------=_Part_3314_15532852.1495550410660
Content-Type: multipart/alternative;
 boundary="----=_Part_3315_1830320558.1495550410663"

------=_Part_3315_1830320558.1495550410663
Content-Type: text/plain; charset="UTF-8"

@AnthonyHall

Yep!  I was, I was myself using something just like it in my projects.  I
just felt like the range based for loop still has some more room for
improvement and changes.  And this change would hopefully make it much more
usable in generic code.

I just posted an update regarding what I think the best design decision
here it, I decided to drop the iterator idea entirely for something
simpler!

On Tuesday, 23 May 2017 03:07:30 UTC-4, Anthony Hall wrote:
>
> You may already be aware of the boost::hana library, but if not: part of
> its design intent is to provide facilities and algorithms for traversal of
> heterogeneously-typed containers much like what's being proposed.  Of
> course, as a C++14 library-based solution, it can't always offer the kind
> of syntactic sugar that's been proposed here with `for constexpr` or these
> expansions of operator++ overloads.
>
> On Tuesday, May 23, 2017 at 12:30:12 AM UTC-6, Avi Kivity wrote:
>>
>> On 05/23/2017 07:10 AM, rmn...@gmail.com wrote:
>>
>> C++17 has a new feature that would improve the functionality of range
>> based for loops to work with begin and end iterators that are not of the
>> same type as proposed by Eric Niebler here
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html.
>>  This is a great feature, as it generalizes the range based for loop to fit
>> scenarios that would otherwise not be possible, essentially making it more
>> adaptable.
>>
>> But something like the following is still not possible using the range
>> based for loop, since the dereferenced iterators must be the same type, and
>> therefore cannot contain any compile time information
>>     for (auto ele : std::make_tuple(1, 2)) {
>>         cout << ele << endl;
>>     }
>>
>>
>>
>> Perhaps:
>>
>>
>>     for constexpr (auto element : std::tuple(1, "a")) {
>>         std::cout << element << std::endl;
>>     }
>>
>> The rules can then be relaxed that operator++ can return new types; the
>> compiler will essentially unroll the loop if that's the case.
>>
>> Iterating through a tuple requires use of minimal amounts of
>> metaprogramming, it is easy to write a small helper that would automate
>> this for us.  But then again, it requires extra work on the programmers
>> part. A language solution seems to be more intuitive to me - generalize the
>> range based for loop to the stage where it can accept a range of different
>> iterator types.
>>
>> You might be thinking that such a change cannot be made without
>> sacrificing runtime efficiency in the range based for loop as it expects
>> the same type for iterators it dereferences.  What I propose is to not use
>> the operator++() method (the pre-increment member function) to increment
>> iterators when they contain a trait that signals that they are heterogenous
>> iterators.  Perhaps this could be enabled with the help of a
>> preferred_increment iterator tag, which if absent will cause the range
>> based for loop to default to prefix operator++(), but if present will make
>> the range based for loop go with the preferred increment approach (which
>> can either be a post-increment and initialization or a reference
>> pre-increment).  With this small change the tuple class can be modified to
>> support iteration.  The iterator for a tuple might look something like the
>> following
>>
>> template <typename... Args>
>> class tuple {
>> public:
>>
>>     // The iterator class is templated with an integer that denotes
>> which
>>     // member of the tuple it must fetch from, the tuple type is included
>>     // for forwarding reasons
>>     template <int index, typename TupleType>
>>     class Iterator {
>>     public:
>>         // this tells the range based for loop to not use the
>> operator++()
>>         // member function to increment the iterator, but rather to use
>> the
>>         // operator++(int) postfix increment method
>>         using preferred_increment = std::post_increment_tag;
>>
>>         // The constructor initializes the iterator with a reference to
>> the
>>         // tuple
>>         Iterator(tuple<Args...>& tup_in) : tup{tup_in} {}
>>
>>         // The dereference operator forwards the tuple and returns the
>> forwarded
>>         // result obtained on a call to std::get<>
>>         decltype(auto) operator*() {
>>             return std::get<index>(std::forward<TupleType>(this->tup));
>>         }
>>
>>         // The iterator only defines a postfix increment, as is needed
>> for
>>         // heterogenosity
>>         auto operator++(int) {
>>             return Iterator<index + 1, TupleType>(this->tup);
>>         }
>>
>>         // return a false for iterators that are not of the same type
>>         template <int index_other, typename TupleType>
>>         constexpr bool operator!=(const Iterator<index_other, TupleType&)
>> {
>>             return index_other != index;
>>         }
>>     };
>>
>>     // The begin() member function returns an iterator type that will
>> return
>>     // lvalue references on dereferencing
>>     auto begin() & {
>>         return Iterator<0, tuple<Args...>&>{*this};
>>     }
>>
>>     // The begin() member function returns an iterator type that will
>> return
>>     // rvalue references on dereferencing
>>     auto begin() && {
>>         // or Iterator<0, tuple<Args...>>{*this};
>>         return Iterator<0, tuple<Args...>&&>{*this};
>>     }
>>
>>     // The end iterator returns an iterator with the sizeof(Args)... as
>> the
>>     // index, so any iterator type that reaches it will compare the same
>>     // The tuple type really doesn't matter here
>>     auto end() {
>>         return Iterator<sizeof(Args)..., tuple<Args...>>{*this};
>>     }
>> };
>>
>>
>> And that would allow the range based for loop to increment the iterator
>> with the heterogenous postfix iterator increment like so
>> for (auto element : std::make_tuple(1, "some string")) {
>>     cout << element << endl;
>> }
>>
>> Of course making an iterator class for a tuple seems to outweigh the
>> benefits, but making such a modification to the range based for loop to
>> generalize it further seems to be a good idea in my mind as it opens up
>> doors for a whole bunch of other things.  Like iteration through a range
>> computed at compile time.  The canonical example here could be through the
>> fibonacci range
>> for (auto val : std::fibonacci{}) {
>>     cout << val << endl;
>> }
>>
>>
>> or iterate through a function's arguments
>> template <typename... Args>
>> void foo(Args&&... args_in) {
>>     auto args = std::forward_as_tuple(std::forward<Args>(args_in)...);
>>     for (auto&& arg : args) {
>>         // ...
>>     }
>> }
>>
>> even something like so will be possible
>> // compile time iteration through a range of integers
>> for (auto index : std::make_integer_sequence<int,10>{}) {
>>     cout << std::get<static_cast<int>(index)>(some_tuple) << endl;
>> }
>>
>> Apologies for the mistakes in the code, I didn't actually compile any of
>> it, it is just a vision of what I hope might come to pass if people like
>> this idea.
>> --
>> 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-proposal...@isocpp.org.
>> To post to this group, send email to std-pr...@isocpp.org.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org?utm_medium=email&utm_source=footer>
>> .
>>
>>
>>

--
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/96eaf12b-c2d2-4146-9d2e-627acd6ac6ed%40isocpp.org.

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

<div dir=3D"ltr">@AnthonyHall<div><br></div><div>Yep! =C2=A0I was, I was my=
self using something just like it in my projects. =C2=A0I just felt like th=
e range based for loop still has some more room for improvement and changes=
.. =C2=A0And this change would hopefully make it much more usable in generic=
 code. =C2=A0</div><div><br></div><div>I just posted an update regarding wh=
at I think the best design decision here it, I decided to drop the iterator=
 idea entirely for something simpler! =C2=A0<br><br>On Tuesday, 23 May 2017=
 03:07:30 UTC-4, Anthony Hall  wrote:<blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
 1ex;"><div dir=3D"ltr">You may already be aware of the boost::hana library=
, but if not: part of its design intent is to provide facilities and algori=
thms for traversal of heterogeneously-typed containers much like what&#39;s=
 being proposed. =C2=A0Of course, as a C++14 library-based solution, it can=
&#39;t always offer the kind of syntactic sugar that&#39;s been proposed he=
re with `for constexpr` or these expansions of operator++ overloads.<br><br=
>On Tuesday, May 23, 2017 at 12:30:12 AM UTC-6, Avi Kivity wrote:<blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
 #ccc solid;padding-left:1ex">
 =20
   =20
 =20
  <div text=3D"#000000" bgcolor=3D"#FFFFFF">
    <div>On 05/23/2017 07:10 AM,
      <a rel=3D"nofollow">rmn...@gmail.com</a> wrote:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">C++17 has a new feature that would improve the
        functionality of range based for loops to work with begin and
        end iterators that are not of the same type as proposed by Eric
        Niebler here
        <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/=
p0184r0.html" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=
=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1=
%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0184r0.html\x26sa\x3dD\x26sntz\x3d=
1\x26usg\x3dAFQjCNHsm16utECLKaIF1azvSKcFVZwR1g&#39;;return true;" onclick=
=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-s=
td.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0184r0.html\x26sa\x3d=
D\x26sntz\x3d1\x26usg\x3dAFQjCNHsm16utECLKaIF1azvSKcFVZwR1g&#39;;return tru=
e;">http://www.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2016/<wbr>p0184=
r0.html</a>.
        =C2=A0This is a great feature, as it generalizes the range based fo=
r
        loop to fit scenarios that would otherwise not be possible,
        essentially making it more adaptable. =C2=A0
        <div><br>
        </div>
        <div>But something like the following is still not possible
          using the range based for loop, since the dereferenced
          iterators must be the same type, and therefore cannot contain
          any compile time information</div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#000">=C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">for</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">(</span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> ele </span><span style=3D"color:#660">:</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">make_tuple</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#066">1</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#066">2</span><span style=3D"c=
olor:#660">))</span><span style=3D"color:#000"> </span><span style=3D"color=
:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 cout </span><span style=3D"colo=
r:#660">&lt;&lt;</span><span style=3D"color:#000"> ele </span><span style=
=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> endl</span><span=
 style=3D"color:#660">;</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
      </div>
    </blockquote>
    <br>
    <br>
    Perhaps:<br>
    <br>
    <br>
    =C2=A0=C2=A0=C2=A0 for constexpr (auto element : std::tuple(1, &quot;a&=
quot;)) {<br>
    =C2=A0 =C2=A0 =C2=A0 =C2=A0 std::cout &lt;&lt; element &lt;&lt; std::en=
dl; <br>
    =C2=A0=C2=A0=C2=A0 }<br>
    <br>
    The rules can then be relaxed that operator++ can return new types;
    the compiler will essentially unroll the loop if that&#39;s the case. <=
br>
    <br>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">
        <div>Iterating through a tuple requires use of minimal amounts
          of metaprogramming, it is easy to write a small helper that
          would automate this for us. =C2=A0But then again, it requires ext=
ra
          work on the programmers part. A language solution seems to be
          more intuitive to me - generalize the range based for loop to
          the stage where it can accept a range of different iterator
          types.=C2=A0</div>
        <div><br>
        </div>
        <div>You might be thinking that such a change cannot be made
          without sacrificing runtime efficiency in the range based for
          loop as it expects the same type for iterators it
          dereferences. =C2=A0What I propose is to not use the <font face=
=3D"courier new, monospace">operator++()</font>=C2=A0method
          (the pre-increment member function) to increment iterators
          when they contain a trait that signals that they are
          heterogenous iterators. =C2=A0Perhaps this could be enabled with
          the help of a <font face=3D"courier new, monospace">preferred_inc=
rement</font><font face=3D"arial, sans-serif">=C2=A0iterator tag, which if =
absent will
            cause the range based for loop to default to prefix
            operator++(), but if present will make the range based for
            loop go with the preferred increment approach (which can
            either be a post-increment and initialization or a reference
            pre-increment). =C2=A0With this small change the tuple class ca=
n
            be modified to support iteration. =C2=A0The iterator for a tupl=
e
            might look something like the following</font></div>
        <div><font face=3D"arial, sans-serif"><br>
          </font></div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#008">template</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#008">typename</span><span style=3D"color:#660">...</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Args</span><span style=3D"c=
olor:#660">&gt;</span><span style=3D"color:#000"><br>
              </span><span style=3D"color:#008">class</span><span style=3D"=
color:#000"> tuple </span><span style=3D"color:#660">{</span><span style=3D=
"color:#000"><br>
              </span><span style=3D"color:#008">public</span><span style=3D=
"color:#660">:</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0<br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The iter=
ator class is
                templated with an integer that denotes which </span><span s=
tyle=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">/</span><fo=
nt color=3D"#000000"><span style=3D"color:#800">/
                  member of the tuple it must fetch from, the tuple type
                  is included</span><span style=3D"color:#000"><br>
                </span></font><span style=3D"color:#000">=C2=A0 =C2=A0 </sp=
an><span style=3D"color:#800">// for
                forwarding reasons</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">template</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</spa=
n><font color=3D"#000088"><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> index</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">typename</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#606">TupleType</span><span =
style=3D"color:#660">&gt;</span></font><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">class</span=
><span style=3D"color:#000"> </span><span style=3D"color:#606">Iterator</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">public</spa=
n><span style=3D"color:#660">:</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// this tells the range based
                for loop to not use the operator++()</span><span style=3D"c=
olor:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// member function to
                increment the iterator, but rather to use the </span><span =
style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// operator++(int) postfix
                increment method</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">using</span><span style=3D"color:#000">
                preferred_increment </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</s=
pan><font color=3D"#000000"><span style=3D"color:#000">post_increment_tag</=
span></font><span style=3D"color:#660">;</span><span style=3D"color:#000"><=
br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// The constructor
                initializes the iterator with a reference to the </span><sp=
an style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// tuple</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">(</span><span style=3D"color:#=
000">tuple</span><span style=3D"color:#660">&lt;</span><span style=3D"color=
:#606">Args</span><span style=3D"color:#660">...&gt;&amp;</span><span style=
=3D"color:#000"> tup_in</span><span style=3D"color:#660">)</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#660">:</span><span style=3D"=
color:#000"> tup</span><span style=3D"color:#660">{</span><span style=3D"co=
lor:#000">tup_in</span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">{}</span><span style=3D"color:=
#000"><br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// The dereference operator
                forwards the tuple and returns the forwarded </span><span s=
tyle=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// result obtained on a call
                to std::get&lt;&gt;</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">decltype</span><span style=3D"color:#660">(</span><span style=3D"color:#=
008">auto</span><span style=3D"color:#660">)</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#008">operator</span><span style=3D"color:#=
660">*()</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">return</span><span style=3D"color:#000"> std</span><span s=
tyle=3D"color:#660">::</span><span style=3D"color:#008">get</span><span sty=
le=3D"color:#080">&lt;index&gt;</span><span style=3D"color:#660">(</span><s=
pan style=3D"color:#000">std</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#000">forward</span><span style=3D"color:#660">&lt;</span>=
<span style=3D"color:#606">T<wbr>upleType</span><span style=3D"color:#660">=
&gt;(</span><span style=3D"color:#008">this</span><span style=3D"color:#660=
">-&gt;</span><span style=3D"color:#000">tup</span><span style=3D"color:#66=
0">));</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#66=
0">}</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// The iterator only defines
                a postfix increment, as is needed for </span><span style=3D=
"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// heterogenosity</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">auto</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>operator</span><span style=3D"color:#660">++(</span><span style=3D"color:#=
008">int</span><span style=3D"color:#660">)</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br=
>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">return</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#606">Iterator</span><span style=3D"color:#660">&lt;</span><span=
 style=3D"color:#000">index </span><span style=3D"color:#660">+</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#066">1</span><span styl=
e=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"=
color:#606">TupleType</span><span style=3D"color:#660">&gt;(</span><span st=
yle=3D"color:#008">this</span><span style=3D"color:#660">-&gt;</span><span =
style=3D"color:#000">tup</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#66=
0">}</span><span style=3D"color:#000"><br>
                <br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// return a false for
                iterators that are not of the same type</span><span style=
=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">template</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">&lt;</span><font color=3D"#000088"><span style=3D"color:#008">int</spa=
n><span style=3D"color:#000">
                  index_other</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">typename</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#606">TupleType</span=
></font><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><b=
r>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">constexpr</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">bool</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">operator</span><span style=3D"color:#660">!=3D(</span><span style=3D"co=
lor:#008">const</span><span style=3D"color:#000"> </span><font color=3D"#66=
0066"><span style=3D"color:#606">Iterator</span><span style=3D"color:#660">=
&lt;</span><span style=3D"color:#000">index_other</span><span style=3D"colo=
r:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">TupleType</span></font><span style=3D"color:#660">&amp;)</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D=
"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color:#008">return</span><span style=3D"color:#000">
                index_other </span><span style=3D"color:#660">!=3D</span><s=
pan style=3D"color:#000"> index</span><span style=3D"color:#660">;</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#66=
0">}</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">};</span><s=
pan style=3D"color:#000"><br>
                <br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The begi=
n() member
                function returns an iterator type that will return</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// lvalue r=
eferences on
                dereferencing</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">begin</span><=
span style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&amp;</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#066">0</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> tuple</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#606">Args</span><span style=3D"color:#660">...&gt;&amp;&gt;{*</span><span =
style=3D"color:#008">this</span><span style=3D"color:#660">};</span><span s=
tyle=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
                =C2=A0 =C2=A0 <br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The begi=
n() member
                function returns an iterator type that will return</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// rvalue r=
eferences on
                dereferencing</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">begin</span><=
span style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// or Iterator&lt;0,
                tuple&lt;Args...&gt;&gt;{*this}; </span><span style=3D"colo=
r:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#066">0</span><span style=3D"color:#660">,</span><span style=3D"color:#00=
0"> tuple</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#606">Args</span><span style=3D"color:#660">...&gt;&amp;&amp;&gt;{*</span><=
span style=3D"color:#008">this</span><span style=3D"color:#660">};</span><s=
pan style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
                <br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The end =
iterator returns
                an iterator with the sizeof(Args)... as the</span><span sty=
le=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// index, s=
o any iterator
                type that reaches it will compare the same</span><span styl=
e=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#800">// The tupl=
e type really
                doesn&#39;t matter here</span><span style=3D"color:#000"><b=
r>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">end</span><sp=
an style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">{</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> </span><span style=3D"color:#60=
6">Iterator</span><span style=3D"color:#660">&lt;</span><span style=3D"colo=
r:#008">sizeof</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#606">Args</span><span style=3D"color:#660">)...,</span><span style=3D"co=
lor:#000"> tuple</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#606">Args</span><span style=3D"color:#660">...&gt;&gt;{*</span><spa=
n style=3D"color:#008">this</span><span style=3D"color:#660">};</span><span=
 style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
              </span><span style=3D"color:#660">};</span><span style=3D"col=
or:#000"><br>
                <br>
              </span></div>
          </code></div>
        <div><font face=3D"arial, sans-serif"><br>
          </font></div>
        <div><font face=3D"arial, sans-serif">And that would allow the
            range based for loop to increment the iterator with the
            heterogenous postfix iterator increment like so</font></div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#008">for</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#008"=
>auto</span><span style=3D"color:#000"> element
              </span><span style=3D"color:#660">:</span><span style=3D"colo=
r:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"color=
:#000">make_tuple</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#066">1</span><span style=3D"color:#660">,</span><span style=3D"color:=
#000"> </span><span style=3D"color:#080">&quot;some
                string&quot;</span><span style=3D"color:#660">))</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"><br>
                =C2=A0 =C2=A0 cout </span><span style=3D"color:#660">&lt;&l=
t;</span><span style=3D"color:#000"> element
              </span><span style=3D"color:#660">&lt;&lt;</span><span style=
=3D"color:#000"> endl</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br>
              </span><span style=3D"color:#660">}</span><span style=3D"colo=
r:#000"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
        <div>
          <div>Of course making an iterator class for a tuple seems to
            outweigh the benefits, but making such a modification to the
            range based for loop to generalize it further seems to be a
            good idea in my mind as it opens up doors for a whole bunch
            of other things. =C2=A0Like iteration through a range computed =
at
            compile time. =C2=A0The canonical example here could be through
            the fibonacci range</div>
          <div style=3D"border:1px solid rgb(187,187,187);background-color:=
rgb(250,250,250);word-wrap:break-word"><code>
              <div><span style=3D"color:#008">for</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#00=
8">auto</span><span style=3D"color:#000"> val </span><span style=3D"color:#=
660">:</span><span style=3D"color:#000"> std</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#000">fibonacci</span><span style=3D"color=
:#660">{})</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">{</span><span style=3D"color:#000"><br>
                  =C2=A0 =C2=A0 cout </span><span style=3D"color:#660">&lt;=
&lt;</span><span style=3D"color:#000"> val </span><span style=3D"color:#660=
">&lt;&lt;</span><span style=3D"color:#000"> endl</span><span style=3D"colo=
r:#660">;</span><span style=3D"color:#000"><br>
                </span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"><br>
                </span></div>
              <div><span style=3D"color:rgb(102,102,0)"><br>
                </span></div>
            </code></div>
        </div>
        <div><br>
        </div>
        <div>or iterate through a function&#39;s arguments</div>
        <div style=3D"background-color:rgb(250,250,250);border:1px solid rg=
b(187,187,187);word-wrap:break-word"><code>
            <div><span style=3D"color:#008">template</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#008">typename</span><span style=3D"color:#660">...</span><span style=3D=
"color:#000"> </span><span style=3D"color:#606">Args</span><span style=3D"c=
olor:#660">&gt;</span><span style=3D"color:#000"><br>
              </span><span style=3D"color:#008">void</span><span style=3D"c=
olor:#000"> foo</span><span style=3D"color:#660">(</span><span style=3D"col=
or:#606">Args</span><span style=3D"color:#660">&amp;&amp;...</span><span st=
yle=3D"color:#000"> args_in</span><span style=3D"color:#660">)</span><span =
style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> args </span><span style=3D"color:#660">=3D</spa=
n><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span=
><span style=3D"color:#000">forward_as_tuple</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">for<wbr>ward</span><span style=3D"color=
:#660">&lt;</span><span style=3D"color:#606">Args</span><span style=3D"colo=
r:#660">&gt;(</span><span style=3D"color:#000">args_in</span><span style=3D=
"color:#660">)...);</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">for</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span =
style=3D"color:#008">auto</span><span style=3D"color:#660">&amp;&amp;</span=
><span style=3D"color:#000"> arg </span><span style=3D"color:#660">:</span>=
<span style=3D"color:#000"> args</span><span style=3D"color:#660">)</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span =
style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#80=
0">// ...</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br>
              </span><span style=3D"color:#660">}</span><span style=3D"colo=
r:#000"><br>
              </span></div>
          </code></div>
        <div><br>
        </div>
        <div>even something like so will be possible</div>
        <div>
          <div style=3D"background-color:rgb(250,250,250);border:1px solid =
rgb(187,187,187);word-wrap:break-word"><code>
              <div><span style=3D"color:#800">// compile time iteration
                  through a range of integers</span><span style=3D"color:#0=
00"><br>
                </span><span style=3D"color:#008">for</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">(</span><font color=3D"#0000=
88"><span style=3D"color:#008">auto</span><span style=3D"color:#000">
                    index </span><span style=3D"color:#660">:</span><span s=
tyle=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span st=
yle=3D"color:#000">make_integer_sequence</span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#008">int</span><span style=3D"color:#660"><=
wbr>,</span><span style=3D"color:#066">10</span><span style=3D"color:#660">=
&gt;{})</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>{</span><span style=3D"color:#000"><br>
                    =C2=A0 =C2=A0 cout </span><span style=3D"color:#660">&l=
t;&lt;</span><span style=3D"color:#000"> std</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#008">get</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#008">static_cast</span><span style=3D"col=
or:#080">&lt;int&gt;</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">inde<wbr>x</span><span style=3D"color:#660">)&gt;(</span><s=
pan style=3D"color:#000">some_tuple</span><span style=3D"color:#660">)</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;&lt;</s=
pan><span style=3D"color:#000">
                    endl</span><span style=3D"color:#660">;</span><span sty=
le=3D"color:#000"><br>
                  </span><span style=3D"color:#660">}</span></font></div>
            </code></div>
        </div>
        <div><br>
        </div>
        <div>Apologies for the mistakes in the code, I didn&#39;t actually
          compile any of it, it is just a vision of what I hope might
          come to pass if people like this idea.=C2=A0</div>
      </div>
      -- <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 email to <a rel=3D"nofollow">std-proposal...@isocpp.org</a>.<=
br>
      To post to this group, send email to <a rel=3D"nofollow">std-pr...@is=
ocpp.org</a>.<br>
      To view this discussion on the web visit <a href=3D"https://groups.go=
ogle.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef=
5bf96%40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" rel=3D"nofol=
low" target=3D"_blank" onmousedown=3D"this.href=3D&#39;https://groups.googl=
e.com/a/isocpp.org/d/msgid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf=
96%40isocpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/ms=
gid/std-proposals/05e0675e-4c5d-4ad4-a1e4-4cf10ef5bf96%40isocpp.org?utm_med=
ium\x3demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.goog=
le.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/05e0675e-4c5d-4ad4-<wbr=
>a1e4-4cf10ef5bf96%40isocpp.org</a><wbr>.<br>
    </blockquote>
    <p><br>
    </p>
  </div>

</blockquote></div></blockquote></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/96eaf12b-c2d2-4146-9d2e-627acd6ac6ed%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/96eaf12b-c2d2-4146-9d2e-627acd6ac6ed=
%40isocpp.org</a>.<br />

------=_Part_3315_1830320558.1495550410663--

------=_Part_3314_15532852.1495550410660--

.


Author: rmn100@gmail.com
Date: Tue, 23 May 2017 08:09:16 -0700 (PDT)
Raw View
------=_Part_3602_1359782442.1495552156896
Content-Type: multipart/alternative;
 boundary="----=_Part_3603_730475139.1495552156897"

------=_Part_3603_730475139.1495552156897
Content-Type: text/plain; charset="UTF-8"

@Nicol Bolas

Thanks for the reply!  While there are other solutions, why not improve the
range based for loop even more?  There was no strict need for sentinels,
but that was added as well.  There were other ways to accomplish the same
thing without them but adding them brings more generalizability to the
construct.  That's why I suggested the change.

Regarding the second thing you said about ele not changing its type, it can
change its type based on what I proposed in the update I just posted,
 since it's initialized every time the loop is run.

On Tuesday, 23 May 2017 10:10:46 UTC-4, Nicol Bolas wrote:
>
>
>
> On Tuesday, May 23, 2017 at 12:10:40 AM UTC-4, rmn...@gmail.com wrote:
>>
>> C++17 has a new feature that would improve the functionality of range
>> based for loops to work with begin and end iterators that are not of the
>> same type as proposed by Eric Niebler here
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html.
>>  This is a great feature, as it generalizes the range based for loop to fit
>> scenarios that would otherwise not be possible, essentially making it more
>> adaptable.
>>
>> But something like the following is still not possible using the range
>> based for loop, since the dereferenced iterators must be the same type, and
>> therefore cannot contain any compile time information
>>     for (auto ele : std::make_tuple(1, 2)) {
>>         cout << ele << endl;
>>     }
>>
>> Iterating through a tuple requires use of minimal amounts of
>> metaprogramming, it is easy to write a small helper that would automate
>> this for us.
>>
>
> No, it's not. It's not even *possible* unless every element of the tuple
> is of the same type (or is implicitly convertible to the same type). `auto
> ele` cannot change its type; it must be of the begin iterator's value_type.
> Which is a static property that cannot change based on where the iterator
> is.
>
> I much prefer we just have this <http://wg21.link/P0535>. It will allow
> plenty of ways to "iterate" over elements of a tuple.
>
> But then again, it requires extra work on the programmers part. A language
>> solution seems to be more intuitive to me - generalize the range based for
>> loop to the stage where it can accept a range of different iterator types.
>>
>
> No.
>

--
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/725dfe07-2b75-4311-91e8-c288a43b2e7b%40isocpp.org.

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

<div dir=3D"ltr"><div>@Nicol Bolas</div><div><br></div>Thanks for the reply=
! =C2=A0While there are other solutions, why not improve the range based fo=
r loop even more? =C2=A0There was no strict need for sentinels, but that wa=
s added as well. =C2=A0There were other ways to accomplish the same thing w=
ithout them but adding them brings more generalizability to the construct. =
=C2=A0That&#39;s why I suggested the change. =C2=A0<div><br></div><div>Rega=
rding the second thing you said about <font face=3D"courier new, monospace"=
>ele</font> not changing its type, it can change its type based on what I p=
roposed in the update I just posted, =C2=A0since it&#39;s initialized every=
 time the loop is run. =C2=A0</div><div><br>On Tuesday, 23 May 2017 10:10:4=
6 UTC-4, Nicol Bolas  wrote:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><br><br>On Tuesday, May 23, 2017 at 12:10:40 AM UTC-4, <a>rm=
n...@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">C++17 has a new feature that would improve the functionality of ra=
nge based for loops to work with begin and end iterators that are not of th=
e same type as proposed by Eric Niebler here <a href=3D"http://www.open-std=
..org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html" rel=3D"nofollow" target=
=3D"_blank" onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\x3d=
http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2=
Fp0184r0.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHsm16utECLKaIF1azvSKc=
FVZwR1g&#39;;return true;" onclick=3D"this.href=3D&#39;http://www.google.co=
m/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpape=
rs%2F2016%2Fp0184r0.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHsm16utECL=
KaIF1azvSKcFVZwR1g&#39;;return true;">http://www.open-std.org/jtc1/<wbr>sc2=
2/wg21/docs/papers/2016/<wbr>p0184r0.html</a>. =C2=A0This is a great featur=
e, as it generalizes the range based for loop to fit scenarios that would o=
therwise not be possible, essentially making it more adaptable. =C2=A0<div>=
<br></div><div>But something like the following is still not possible using=
 the range based for loop, since the dereferenced iterators must be the sam=
e type, and therefore cannot contain any compile time information</div><div=
 style=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187,18=
7);word-wrap:break-word"><code><div><span style=3D"color:#000">=C2=A0 =C2=
=A0 </span><span style=3D"color:#008">for</span><span style=3D"color:#000">=
 </span><span style=3D"color:#660">(</span><span style=3D"color:#008">auto<=
/span><span style=3D"color:#000"> ele </span><span style=3D"color:#660">:</=
span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</s=
pan><span style=3D"color:#000">make_tuple</span><span style=3D"color:#660">=
(</span><span style=3D"color:#066">1</span><span style=3D"color:#660">,</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#066">2</span><s=
pan style=3D"color:#660">))</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 cout </span><span style=3D"color:#660">&lt;&lt;</span><span s=
tyle=3D"color:#000"> ele </span><span style=3D"color:#660">&lt;&lt;</span><=
span style=3D"color:#000"> endl</span><span style=3D"color:#660">;</span><s=
pan style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660=
">}</span><span style=3D"color:#000"><br></span></div></code></div><div><br=
></div></div></blockquote><div></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div>Iterating through a tuple requires use of minimal a=
mounts of metaprogramming, it is easy to write a small helper that would au=
tomate this for us.</div></div></blockquote><div><br>No, it&#39;s not. It&#=
39;s not even <i>possible</i> unless every element of the tuple is of the s=
ame type (or is implicitly convertible to the same type). `auto ele` cannot=
 change its type; it must be of the begin iterator&#39;s value_type. Which =
is a static property that cannot change based on where the iterator is.<br>=
<br>I much prefer we just <a href=3D"http://wg21.link/P0535" target=3D"_bla=
nk" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.com/=
url?q\x3dhttp%3A%2F%2Fwg21.link%2FP0535\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNGc2AH2VWCJhvJ-rsA5KfEGK2Ubkw&#39;;return true;" onclick=3D"this.href=
=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwg21.link%2FP0535\x26sa=
\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGc2AH2VWCJhvJ-rsA5KfEGK2Ubkw&#39;;return=
 true;">have this</a>. It will allow plenty of ways to &quot;iterate&quot; =
over elements of a tuple.<br><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div>But then again, it requires extra work on the pro=
grammers part. A language solution seems to be more intuitive to me - gener=
alize the range based for loop to the stage where it can accept a range of =
different iterator types.</div></div></blockquote><div><br>No.</div></div><=
/blockquote></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/725dfe07-2b75-4311-91e8-c288a43b2e7b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/725dfe07-2b75-4311-91e8-c288a43b2e7b=
%40isocpp.org</a>.<br />

------=_Part_3603_730475139.1495552156897--

------=_Part_3602_1359782442.1495552156896--

.


Author: Barry Revzin <barry.revzin@gmail.com>
Date: Tue, 23 May 2017 08:26:56 -0700 (PDT)
Raw View
------=_Part_3488_1881758620.1495553216389
Content-Type: multipart/alternative;
 boundary="----=_Part_3489_1782173732.1495553216389"

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



On Monday, May 22, 2017 at 11:10:40 PM UTC-5, rmn...@gmail.com wrote:
>
> C++17 has a new feature that would improve the functionality of range=20
> based for loops to work with begin and end iterators that are not of the=
=20
> same type as proposed by Eric Niebler here=20
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html.=20
>  This is a great feature, as it generalizes the range based for loop to f=
it=20
> scenarios that would otherwise not be possible, essentially making it mor=
e=20
> adaptable. =20
>
> But something like the following is still not possible using the range=20
> based for loop, since the dereferenced iterators must be the same type, a=
nd=20
> therefore cannot contain any compile time information
>     for (auto ele : std::make_tuple(1, 2)) {
>         cout << ele << endl;
>     }
>
> Iterating through a tuple requires use of minimal amounts of=20
> metaprogramming, it is easy to write a small helper that would automate=
=20
> this for us.  But then again, it requires extra work on the programmers=
=20
> part. A language solution seems to be more intuitive to me - generalize t=
he=20
> range based for loop to the stage where it can accept a range of differen=
t=20
> iterator types.=20
>

See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0589r0.pdf

From Botond's trip report=20
<https://botondballo.wordpress.com/2017/03/27/trip-report-c-standards-meeti=
ng-in-kona-february-2017/>
:

Concerns with this specific proposal included performance considerations=20
> (for example, it makes it very easy to write innocent-looking code that=
=20
> triggers a lot of template instantiations and is expensive to compile), a=
nd=20
> the fact that it didn=E2=80=99t generalize to some use cases (such as cas=
es where=20
> you want the type of a result to depend on logic in your =E2=80=9Cloop=E2=
=80=9D). Further=20
> exploration of the topic was encouraged.

--=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/f8b9953b-f1e1-4bf6-8fd7-130ce156432a%40isocpp.or=
g.

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

<div dir=3D"ltr"><br><br>On Monday, May 22, 2017 at 11:10:40 PM UTC-5, rmn.=
...@gmail.com wrote:<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">C++17 has a new feature that would improve the functionality of range=
 based for loops to work with begin and end iterators that are not of the s=
ame type as proposed by Eric Niebler here <a href=3D"http://www.open-std.or=
g/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html" target=3D"_blank" rel=3D"no=
follow" onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp=
%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp01=
84r0.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHsm16utECLKaIF1azvSKcFVZw=
R1g&#39;;return true;" onclick=3D"this.href=3D&#39;http://www.google.com/ur=
l?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2=
F2016%2Fp0184r0.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHsm16utECLKaIF=
1azvSKcFVZwR1g&#39;;return true;">http://www.open-std.org/jtc1/<wbr>sc22/wg=
21/docs/papers/2016/<wbr>p0184r0.html</a>. =C2=A0This is a great feature, a=
s it generalizes the range based for loop to fit scenarios that would other=
wise not be possible, essentially making it more adaptable. =C2=A0<div><br>=
</div><div>But something like the following is still not possible using the=
 range based for loop, since the dereferenced iterators must be the same ty=
pe, and therefore cannot contain any compile time information</div><div sty=
le=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187,187);w=
ord-wrap:break-word"><code><div><span style=3D"color:#000">=C2=A0 =C2=A0 </=
span><span style=3D"color:#008">for</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> ele </span><span style=3D"color:#660">:</span><=
span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><s=
pan style=3D"color:#000">make_tuple</span><span style=3D"color:#660">(</spa=
n><span style=3D"color:#066">1</span><span style=3D"color:#660">,</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#066">2</span><span st=
yle=3D"color:#660">))</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 cout </span><span style=3D"color:#660">&lt;&lt;</span><span style=
=3D"color:#000"> ele </span><span style=3D"color:#660">&lt;&lt;</span><span=
 style=3D"color:#000"> endl</span><span style=3D"color:#660">;</span><span =
style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}<=
/span><span style=3D"color:#000"><br></span></div></code></div><div><br>Ite=
rating through a tuple requires use of minimal amounts of metaprogramming, =
it is easy to write a small helper that would automate this for us. =C2=A0B=
ut then again, it requires extra work on the programmers part. A language s=
olution seems to be more intuitive to me - generalize the range based for l=
oop to the stage where it can accept a range of different iterator types.=
=C2=A0</div></div></blockquote><div><br></div><div>See http://www.open-std.=
org/jtc1/sc22/wg21/docs/papers/2017/p0589r0.pdf</div><div><br></div><div>Fr=
om Botond&#39;s <a href=3D"https://botondballo.wordpress.com/2017/03/27/tri=
p-report-c-standards-meeting-in-kona-february-2017/">trip report</a>:</div>=
<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0=
px 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">Co=
ncerns with this specific proposal included performance considerations (for=
 example, it makes it very easy to write innocent-looking code that trigger=
s a lot of template instantiations and is expensive to compile), and the fa=
ct that it didn=E2=80=99t generalize to some use cases (such as cases where=
 you want the type of a result to depend on logic in your =E2=80=9Cloop=E2=
=80=9D). Further exploration of the topic was encouraged.</blockquote></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/f8b9953b-f1e1-4bf6-8fd7-130ce156432a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f8b9953b-f1e1-4bf6-8fd7-130ce156432a=
%40isocpp.org</a>.<br />

------=_Part_3489_1782173732.1495553216389--

------=_Part_3488_1881758620.1495553216389--

.


Author: rmn100@gmail.com
Date: Tue, 23 May 2017 08:44:49 -0700 (PDT)
Raw View
------=_Part_3687_1963474991.1495554290012
Content-Type: multipart/alternative;
 boundary="----=_Part_3688_575572109.1495554290012"

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

@Barry Revzin

It seems like this is the second time I have made a post on this group that=
=20
has just recently been explored elsewhere that I didn't know about..

Couldn't the problem of innocent-looking code causing a lot of=20
instantiations be simply resolved by limiting the number of iterations that=
=20
are allowed in such a setting?  The same way infinite compile time=20
recursion is prevented without the use of special flags in g++?

Also about the loop not generalizing to cases where you want the type of a=
=20
result to depend on the logic in a loop, why can you not simply use a=20
constexpr if in the loop and eliminate the problem?

I feel like the idea is still good because there are a lot of cases where=
=20
you just need to loop over the elements of a compile time range, and=20
perform computations on them.  An example could be the compile time=20
overload of std::future::when_all as opposed to the runtime overload=20
accepting two iterators.

On Tuesday, 23 May 2017 11:26:56 UTC-4, Barry Revzin wrote:
>
>
>
> On Monday, May 22, 2017 at 11:10:40 PM UTC-5, rmn...@gmail.com wrote:
>>
>> C++17 has a new feature that would improve the functionality of range=20
>> based for loops to work with begin and end iterators that are not of the=
=20
>> same type as proposed by Eric Niebler here=20
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html.=20
>>  This is a great feature, as it generalizes the range based for loop to =
fit=20
>> scenarios that would otherwise not be possible, essentially making it mo=
re=20
>> adaptable. =20
>>
>> But something like the following is still not possible using the range=
=20
>> based for loop, since the dereferenced iterators must be the same type, =
and=20
>> therefore cannot contain any compile time information
>>     for (auto ele : std::make_tuple(1, 2)) {
>>         cout << ele << endl;
>>     }
>>
>> Iterating through a tuple requires use of minimal amounts of=20
>> metaprogramming, it is easy to write a small helper that would automate=
=20
>> this for us.  But then again, it requires extra work on the programmers=
=20
>> part. A language solution seems to be more intuitive to me - generalize =
the=20
>> range based for loop to the stage where it can accept a range of differe=
nt=20
>> iterator types.=20
>>
>
> See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0589r0.pdf
>
> From Botond's trip report=20
> <https://botondballo.wordpress.com/2017/03/27/trip-report-c-standards-mee=
ting-in-kona-february-2017/>
> :
>
> Concerns with this specific proposal included performance considerations=
=20
>> (for example, it makes it very easy to write innocent-looking code that=
=20
>> triggers a lot of template instantiations and is expensive to compile), =
and=20
>> the fact that it didn=E2=80=99t generalize to some use cases (such as ca=
ses where=20
>> you want the type of a result to depend on logic in your =E2=80=9Cloop=
=E2=80=9D). Further=20
>> exploration of the topic was encouraged.
>
>

--=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/c922b62b-31c4-4c5f-88b2-9246024d54ea%40isocpp.or=
g.

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

<div dir=3D"ltr">@Barry Revzin<div><br></div><div>It seems like this is the=
 second time I have made a post on this group that has just recently been e=
xplored elsewhere that I didn&#39;t know about..</div><div><br></div><div>C=
ouldn&#39;t the problem of innocent-looking code causing a lot of instantia=
tions be simply resolved by limiting the number of iterations that are allo=
wed in such a setting? =C2=A0The same way infinite compile time recursion i=
s prevented without the use of special flags in g++?</div><div><br></div><d=
iv>Also about the loop not generalizing to cases where you want the type of=
 a result to depend on the logic in a loop, why can you not simply use a co=
nstexpr if in the loop and eliminate the problem?</div><div><br></div><div>=
I feel like the idea is still good because there are a lot of cases where y=
ou just need to loop over the elements of a compile time range, and perform=
 computations on them. =C2=A0An example could be the compile time overload =
of <font face=3D"courier new, monospace">std::future::when_all</font> as op=
posed to the runtime overload accepting two iterators.</div><div><br>On Tue=
sday, 23 May 2017 11:26:56 UTC-4, Barry Revzin  wrote:<blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><br><br>On Monday, May 22, 2017 at=
 11:10:40 PM UTC-5, <a>rmn...@gmail.com</a> wrote:<blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr">C++17 has a new feature that would improve =
the functionality of range based for loops to work with begin and end itera=
tors that are not of the same type as proposed by Eric Niebler here <a href=
=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0184r0.html" r=
el=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#39;http://ww=
w.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2F=
docs%2Fpapers%2F2016%2Fp0184r0.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjC=
NHsm16utECLKaIF1azvSKcFVZwR1g&#39;;return true;" onclick=3D"this.href=3D&#3=
9;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc2=
2%2Fwg21%2Fdocs%2Fpapers%2F2016%2Fp0184r0.html\x26sa\x3dD\x26sntz\x3d1\x26u=
sg\x3dAFQjCNHsm16utECLKaIF1azvSKcFVZwR1g&#39;;return true;">http://www.open=
-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2016/<wbr>p0184r0.html</a>. =C2=A0=
This is a great feature, as it generalizes the range based for loop to fit =
scenarios that would otherwise not be possible, essentially making it more =
adaptable. =C2=A0<div><br></div><div>But something like the following is st=
ill not possible using the range based for loop, since the dereferenced ite=
rators must be the same type, and therefore cannot contain any compile time=
 information</div><div style=3D"background-color:rgb(250,250,250);border:1p=
x solid rgb(187,187,187);word-wrap:break-word"><code><div><span style=3D"co=
lor:#000">=C2=A0 =C2=A0 </span><span style=3D"color:#008">for</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">(</span><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> ele </span><span sty=
le=3D"color:#660">:</span><span style=3D"color:#000"> std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">make_tuple</span><span =
style=3D"color:#660">(</span><span style=3D"color:#066">1</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#066">2</span><span style=3D"color:#660">))</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000=
"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 cout </span><span style=3D"color:#660">&l=
t;&lt;</span><span style=3D"color:#000"> ele </span><span style=3D"color:#6=
60">&lt;&lt;</span><span style=3D"color:#000"> endl</span><span style=3D"co=
lor:#660">;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span=
 style=3D"color:#660">}</span><span style=3D"color:#000"><br></span></div><=
/code></div><div><br>Iterating through a tuple requires use of minimal amou=
nts of metaprogramming, it is easy to write a small helper that would autom=
ate this for us. =C2=A0But then again, it requires extra work on the progra=
mmers part. A language solution seems to be more intuitive to me - generali=
ze the range based for loop to the stage where it can accept a range of dif=
ferent iterator types.=C2=A0</div></div></blockquote><div><br></div><div>Se=
e <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0589r=
0.pdf" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;h=
ttp://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2=
Fwg21%2Fdocs%2Fpapers%2F2017%2Fp0589r0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg\x=
3dAFQjCNHo_z56PfjswdyRXRfRdD1Z_UpJFw&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc=
1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2017%2Fp0589r0.pdf\x26sa\x3dD\x26sntz\x3d=
1\x26usg\x3dAFQjCNHo_z56PfjswdyRXRfRdD1Z_UpJFw&#39;;return true;">http://ww=
w.open-std.org/jtc1/<wbr>sc22/wg21/docs/papers/2017/<wbr>p0589r0.pdf</a></d=
iv><div><br></div><div>From Botond&#39;s <a href=3D"https://botondballo.wor=
dpress.com/2017/03/27/trip-report-c-standards-meeting-in-kona-february-2017=
/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https=
://www.google.com/url?q\x3dhttps%3A%2F%2Fbotondballo.wordpress.com%2F2017%2=
F03%2F27%2Ftrip-report-c-standards-meeting-in-kona-february-2017%2F\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNECIV9PznVw5WYLcFFWf2UmomITdQ&#39;;return t=
rue;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%=
2F%2Fbotondballo.wordpress.com%2F2017%2F03%2F27%2Ftrip-report-c-standards-m=
eeting-in-kona-february-2017%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNECI=
V9PznVw5WYLcFFWf2UmomITdQ&#39;;return true;">trip report</a>:</div><div><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;=
border-left:1px solid rgb(204,204,204);padding-left:1ex">Concerns with this=
 specific proposal included performance considerations (for example, it mak=
es it very easy to write innocent-looking code that triggers a lot of templ=
ate instantiations and is expensive to compile), and the fact that it didn=
=E2=80=99t generalize to some use cases (such as cases where you want the t=
ype of a result to depend on logic in your =E2=80=9Cloop=E2=80=9D). Further=
 exploration of the topic was encouraged.</blockquote></div></blockquote></=
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/c922b62b-31c4-4c5f-88b2-9246024d54ea%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c922b62b-31c4-4c5f-88b2-9246024d54ea=
%40isocpp.org</a>.<br />

------=_Part_3688_575572109.1495554290012--

------=_Part_3687_1963474991.1495554290012--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 23 May 2017 09:34:16 -0700 (PDT)
Raw View
------=_Part_3720_1057249237.1495557256704
Content-Type: multipart/alternative;
 boundary="----=_Part_3721_1202321977.1495557256704"

------=_Part_3721_1202321977.1495557256704
Content-Type: text/plain; charset="UTF-8"

On Tuesday, May 23, 2017 at 11:09:17 AM UTC-4, rmn...@gmail.com wrote:
>
> @Nicol Bolas
>
> Thanks for the reply!  While there are other solutions, why not improve
> the range based for loop even more?  There was no strict need for
> sentinels, but that was added as well.
>

Yes, there are strict needs for sentinels. That's why the Range TS added
them; they're more efficient than having to create end iterators in many
cases.


> There were other ways to accomplish the same thing without them but adding
> them brings more generalizability to the construct.  That's why I suggested
> the change.
>

But it's not "generalizability"; it's a *completely different* construct,
which requires a completely different implementation that has completely
different behavior.

This is not some minor tweaking of range-based `for`. It's a fundamentally
different thing in every single way; it just happens to be wearing the same
skin as range-based `for`.

--
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/53ff2c55-777e-4fb7-ae99-0c1299ca9fd9%40isocpp.org.

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

<div dir=3D"ltr">On Tuesday, May 23, 2017 at 11:09:17 AM UTC-4, rmn...@gmai=
l.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div>@Nicol Bolas</div><div><br></div>Thanks for the reply! =C2=A0While ther=
e are other solutions, why not improve the range based for loop even more? =
=C2=A0There was no strict need for sentinels, but that was added as well.</=
div></blockquote><div><br>Yes, there are strict needs for sentinels. That&#=
39;s why the Range TS added them; they&#39;re more efficient than having to=
 create end iterators in many cases.<br>=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div>There were other ways to accomplish the same thi=
ng without them but adding them brings more generalizability to the constru=
ct. =C2=A0That&#39;s why I suggested the change.</div></blockquote><div><br=
>But it&#39;s not &quot;generalizability&quot;; it&#39;s a <i>completely di=
fferent</i> construct, which requires a completely different implementation=
 that has completely different behavior.<br><br>This is not some minor twea=
king of range-based `for`. It&#39;s a fundamentally different thing in ever=
y single way; it just happens to be wearing the same skin as range-based `f=
or`.<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/53ff2c55-777e-4fb7-ae99-0c1299ca9fd9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/53ff2c55-777e-4fb7-ae99-0c1299ca9fd9=
%40isocpp.org</a>.<br />

------=_Part_3721_1202321977.1495557256704--

------=_Part_3720_1057249237.1495557256704--

.