Topic: Limitations of make_integer_sequence<>, and


Author: Amit Jain <amit.jain@sbgenomics.com>
Date: Mon, 9 Nov 2015 12:59:50 -0800 (PST)
Raw View
------=_Part_1397_751255479.1447102790795
Content-Type: multipart/alternative;
 boundary="----=_Part_1398_2000289500.1447102790795"

------=_Part_1398_2000289500.1447102790795
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hello,

I stumbled upon a limitation of std::make_integer_sequence<> template,=20
while trying to make a statically intialised character conversion table. I=
=20
have been in correspondence with Daniel Kr=C3=BCgler about ways to fix it; =
he=20
encouraged me to post the problem and my proposed solution here.=20

The problem:
make_integer_sequence<typename T, T > can not make all possible contiguous=
=20
sequences of integers of type T. By design it excludes sequences containing=
=20
negative integers (for signed T). Also, it can not make sequences=20
containing all positive numbers for unsigned integers. Specifically,=20
numeric_limits::max<T>() can not be part of a sequence made by=20
make_integer_sequence<typename U, U> where U is an unsigned integral type.=
=20
This is a consequence of the fact that U is used to encode the count N of=
=20
elements in the resulting integer_sequence<0, 1, ..., N-1>.

A generic fix for this is not possible because there is no type able to=20
represent numeric_limits<uintmax_t>::max() + 1.

After some thought, I think the best way forward is to have new make_*=20
templates that provide functionality missing from make_integer_sequence. I=
=20
am basing my suggestions on the assumption that the most common use of=20
integer_sequence<> template is to construct intialiser lists, for=20
aggregates, as well as containers.

(I have C++14 compliant implementations available for all of the proposals)

1.
For the specific problem mentioned above, I propose a new template,=20
make_interval_sequence<typename T, T start, T end> to represent all=20
integers in the closed interval [start, end]. There is no requirement that=
=20
start be less than end. This can represent all possible contiguous=20
sequences. It cannot be used to create an empty sequence.

2.
I propose another template, make_uniform_sequence<typename T, size_t N, T=
=20
C> that would construct an integer_sequence<T, C, ..., C>. This would be=20
useful for initialising T[] and std::array<T, N> to a given value. I=20
believe this would prevent many many programmers having to reinvent this=20
idiom.

While I am at it, I would also like to propose constexpr function templates=
=20
that return intialised arrays, Specifically,

3.
a) return array of size N with each element initalised to a given C:
template <typename T, size_t N, T C=3DT{}>
constexpr auto make_filled_array()  -> std::array<T, N>
{...}

b) return array of size N with each element intialised to an integer in the=
=20
given interval:
template <typename T, T Cb, T Ce>
constexpr auto make_array_spanning()
    -> std::array<T, detail_::span_count(Cb, Ce)>
{...}

c) return array with elements initialised to a function applied to each=20
element of the specified sequence:
template<typename T, typename F, typename N, N... values>    // F is=20
aconstexpr callable with T F(N)
constexpr auto eval_discrete_function(detail_::seq<N, values...> &&helper,=
=20
F &&xf)
    -> std::array<T, sizeof...(values)>
{  return {{xf(values)...}}; } // result_of<F(N)::type should convert to T

and

template<typename F, typename N, N... values>
constexpr auto eval_discrete_function(detail_::seq<N, values...> &&helper,=
=20
F &&xf)
    -> std::array<typename std::result_of<F(N)>::type, sizeof...(values)>
{...}

Please consider these suggestions, and let me know whether you can see=20
enough value in any of them to merit a fully-fledged proposal. While I have=
=20
no experience of writing proposals for additions to the standard, Daniel=20
has kindly offered to help me through the process.

Thank you.

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_1398_2000289500.1447102790795
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hello,<br><br>I stumbled upon a limitation of std::make_in=
teger_sequence&lt;&gt; template, while trying to make a statically intialis=
ed character conversion table. I have been in correspondence with Daniel Kr=
=C3=BCgler about ways to fix it; he encouraged me to post the problem and m=
y proposed solution here. <br><br>The problem:<br>make_integer_sequence&lt;=
typename T, T &gt; can not make all possible contiguous sequences of intege=
rs of type T. By design it excludes sequences containing negative integers =
(for signed T). Also, it can not make sequences containing all positive num=
bers for unsigned integers. Specifically, numeric_limits::max&lt;T&gt;() ca=
n not be part of a sequence made by make_integer_sequence&lt;typename U, U&=
gt; where U is an unsigned integral type. This is a consequence of the fact=
 that U is used to encode the count N of elements in the resulting integer_=
sequence&lt;0, 1, ..., N-1&gt;.<br><br>A generic fix for this is not possib=
le because there is no type able to represent numeric_limits&lt;uintmax_t&g=
t;::max() + 1.<br><br>After some thought, I think the best way forward is t=
o have new make_*=20
templates that provide functionality missing from make_integer_sequence. I =
am basing my suggestions on the assumption that the most common use of inte=
ger_sequence&lt;&gt; template is to construct intialiser lists, for aggrega=
tes, as well as containers.<br><br>(I have C++14 compliant implementations =
available for all of the proposals)<br><br>1.<br>For the specific problem m=
entioned above, I propose a new template, make_interval_sequence&lt;typenam=
e T, T start, T end&gt; to represent all integers in the closed interval [s=
tart, end]. There is no requirement that start be less than end. This can r=
epresent all possible contiguous sequences. It cannot be used to create an =
empty sequence.<br><br>2.<br>I propose another template, make_uniform_seque=
nce&lt;typename T, size_t N, T C&gt; that would construct an integer_sequen=
ce&lt;T, C, ..., C&gt;. This would be useful for initialising T[] and std::=
array&lt;T, N&gt; to a given value. I believe this would prevent many many =
programmers having to reinvent this idiom.<br><br>While I am at it, I would=
 also like to propose constexpr function templates that return intialised a=
rrays, Specifically,<br><br>3.<br>a) return array of size N with each eleme=
nt initalised to a given C:<br>template &lt;typename T, size_t N, T C=3DT{}=
&gt;<br>constexpr auto make_filled_array()=C2=A0 -&gt; std::array&lt;T, N&g=
t;<br>{...}<br><br>b) return array of size N with each element intialised t=
o an integer in the given interval:<br>template &lt;typename T, T Cb, T Ce&=
gt;<br>constexpr auto make_array_spanning()<br>=C2=A0=C2=A0=C2=A0 -&gt; std=
::array&lt;T, detail_::span_count(Cb, Ce)&gt;<br>{...}<br><br>c) return arr=
ay with elements initialised to a function applied to each element of the s=
pecified sequence:<br>template&lt;typename T, typename F, typename N, N... =
values&gt;=C2=A0=C2=A0=C2=A0 // F is aconstexpr callable with T F(N)<br>con=
stexpr auto eval_discrete_function(detail_::seq&lt;N, values...&gt; &amp;&a=
mp;helper, F &amp;&amp;xf)<br>=C2=A0=C2=A0=C2=A0 -&gt; std::array&lt;T, siz=
eof...(values)&gt;<br>{=C2=A0 return {{xf(values)...}}; } // result_of&lt;F=
(N)::type should convert to T<br><br>and<br><br>template&lt;typename F, typ=
ename N, N... values&gt;<br>constexpr auto eval_discrete_function(detail_::=
seq&lt;N, values...&gt; &amp;&amp;helper, F &amp;&amp;xf)<br>=C2=A0=C2=A0=
=C2=A0 -&gt; std::array&lt;typename std::result_of&lt;F(N)&gt;::type, sizeo=
f...(values)&gt;<br>{...}<br><br>Please consider these suggestions, and let=
 me know whether you can see enough value in any of them to merit a fully-f=
ledged proposal. While I have no experience of writing proposals for additi=
ons to the standard, Daniel has kindly offered to help me through the proce=
ss.<br><br>Thank you.<br><br></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1398_2000289500.1447102790795--
------=_Part_1397_751255479.1447102790795--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 9 Nov 2015 16:30:01 -0800
Raw View
--001a1143f7987165d8052424cfe2
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Mon, Nov 9, 2015 at 12:59 PM, Amit Jain <amit.jain@sbgenomics.com> wrote=
:

> Hello,
>
> I stumbled upon a limitation of std::make_integer_sequence<> template,
> while trying to make a statically intialised character conversion table. =
I
> have been in correspondence with Daniel Kr=C3=BCgler about ways to fix it=
; he
> encouraged me to post the problem and my proposed solution here.
>
> The problem:
> make_integer_sequence<typename T, T > can not make all possible contiguou=
s
> sequences of integers of type T. By design it excludes sequences containi=
ng
> negative integers (for signed T). Also, it can not make sequences
> containing all positive numbers for unsigned integers. Specifically,
> numeric_limits::max<T>() can not be part of a sequence made by
> make_integer_sequence<typename U, U> where U is an unsigned integral type=
..
> This is a consequence of the fact that U is used to encode the count N of
> elements in the resulting integer_sequence<0, 1, ..., N-1>.
>
> A generic fix for this is not possible because there is no type able to
> represent numeric_limits<uintmax_t>::max() + 1.
>

So what? No compiler will be able to expand a pack with that many elements.


> After some thought, I think the best way forward is to have new make_*
> templates that provide functionality missing from make_integer_sequence. =
I
> am basing my suggestions on the assumption that the most common use of
> integer_sequence<> template is to construct intialiser lists, for
> aggregates, as well as containers.
>
> (I have C++14 compliant implementations available for all of the proposal=
s)
>
> 1.
> For the specific problem mentioned above, I propose a new template,
> make_interval_sequence<typename T, T start, T end> to represent all
> integers in the closed interval [start, end]. There is no requirement tha=
t
> start be less than end. This can represent all possible contiguous
> sequences. It cannot be used to create an empty sequence.
>

Using a closed interval here is not a good match for the usual C++ model of
half-open ranges.

2.
> I propose another template, make_uniform_sequence<typename T, size_t N, T
> C> that would construct an integer_sequence<T, C, ..., C>. This would be
> useful for initialising T[] and std::array<T, N> to a given value. I
> believe this would prevent many many programmers having to reinvent this
> idiom.
>

This seems like a potentially disastrous thing to encourage. Compare:

  T x[1000000];
  for (auto &v : x) { v =3D C; }

versus

  T x[1000000] =3D { pack_of_1000000_Cs ...};

The former will emit a small loop, and the compiler is likely to turn it
into memset or similar. The latter will emit (and create an AST or similar
for) a *huge* unrolled initializer, and will likely have an *extremely*
long compilation time and high memory usage, if it doesn't crash your
compiler outright. Plus it's really awkward to use (you need function
template or a class template partial specialization to unpack your
sequence).

While I am at it, I would also like to propose constexpr function templates
> that return intialised arrays, Specifically,
>
> 3.
> a) return array of size N with each element initalised to a given C:
> template <typename T, size_t N, T C=3DT{}>
> constexpr auto make_filled_array()  -> std::array<T, N>
> {...}
>
> b) return array of size N with each element intialised to an integer in
> the given interval:
> template <typename T, T Cb, T Ce>
> constexpr auto make_array_spanning()
>     -> std::array<T, detail_::span_count(Cb, Ce)>
> {...}
>
> c) return array with elements initialised to a function applied to each
> element of the specified sequence:
> template<typename T, typename F, typename N, N... values>    // F is
> aconstexpr callable with T F(N)
> constexpr auto eval_discrete_function(detail_::seq<N, values...> &&helper=
,
> F &&xf)
>     -> std::array<T, sizeof...(values)>
> {  return {{xf(values)...}}; } // result_of<F(N)::type should convert to =
T
>
> and
>
> template<typename F, typename N, N... values>
> constexpr auto eval_discrete_function(detail_::seq<N, values...> &&helper=
,
> F &&xf)
>     -> std::array<typename std::result_of<F(N)>::type, sizeof...(values)>
> {...}
>

This seems much more reasonable, and has the advantage that the compiler
can in many cases choose to run the initializer at runtime if it's for a
too-large array.


> Please consider these suggestions, and let me know whether you can see
> enough value in any of them to merit a fully-fledged proposal. While I ha=
ve
> no experience of writing proposals for additions to the standard, Daniel
> has kindly offered to help me through the process.
>
> Thank you.
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--001a1143f7987165d8052424cfe2
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Nov 9, 2015 at 12:59 PM, Amit Jain <span dir=3D"ltr">&lt;<a href=3D"mai=
lto:amit.jain@sbgenomics.com" target=3D"_blank">amit.jain@sbgenomics.com</a=
>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 =
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Hell=
o,<br><br>I stumbled upon a limitation of std::make_integer_sequence&lt;&gt=
; template, while trying to make a statically intialised character conversi=
on table. I have been in correspondence with Daniel Kr=C3=BCgler about ways=
 to fix it; he encouraged me to post the problem and my proposed solution h=
ere. <br><br>The problem:<br>make_integer_sequence&lt;typename T, T &gt; ca=
n not make all possible contiguous sequences of integers of type T. By desi=
gn it excludes sequences containing negative integers (for signed T). Also,=
 it can not make sequences containing all positive numbers for unsigned int=
egers. Specifically, numeric_limits::max&lt;T&gt;() can not be part of a se=
quence made by make_integer_sequence&lt;typename U, U&gt; where U is an uns=
igned integral type. This is a consequence of the fact that U is used to en=
code the count N of elements in the resulting integer_sequence&lt;0, 1, ...=
, N-1&gt;.<br><br>A generic fix for this is not possible because there is n=
o type able to represent numeric_limits&lt;uintmax_t&gt;::max() + 1.<br></d=
iv></blockquote><div><br></div><div>So what? No compiler will be able to ex=
pand a pack with that many elements.</div><div>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr">After some thought, I think the best way fo=
rward is to have new make_*=20
templates that provide functionality missing from make_integer_sequence. I =
am basing my suggestions on the assumption that the most common use of inte=
ger_sequence&lt;&gt; template is to construct intialiser lists, for aggrega=
tes, as well as containers.<br><br>(I have C++14 compliant implementations =
available for all of the proposals)<br><br>1.<br>For the specific problem m=
entioned above, I propose a new template, make_interval_sequence&lt;typenam=
e T, T start, T end&gt; to represent all integers in the closed interval [s=
tart, end]. There is no requirement that start be less than end. This can r=
epresent all possible contiguous sequences. It cannot be used to create an =
empty sequence.<br></div></blockquote><div><br></div><div>Using a closed in=
terval here is not a good match for the usual C++ model of half-open ranges=
..</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0=
 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">2.<br=
>I propose another template, make_uniform_sequence&lt;typename T, size_t N,=
 T C&gt; that would construct an integer_sequence&lt;T, C, ..., C&gt;. This=
 would be useful for initialising T[] and std::array&lt;T, N&gt; to a given=
 value. I believe this would prevent many many programmers having to reinve=
nt this idiom.<br></div></blockquote><div><br></div><div>This seems like a =
potentially disastrous thing to encourage. Compare:</div><div><br></div><di=
v>=C2=A0 T x[1000000];</div><div>=C2=A0 for (auto &amp;v : x) { v =3D C; }<=
/div><div><br></div><div>versus</div><div><br></div><div>=C2=A0 T x[1000000=
] =3D { pack_of_1000000_Cs ...};</div><div><br></div><div>The former will e=
mit a small loop, and the compiler is likely to turn it into memset or simi=
lar. The latter will emit (and create an AST or similar for) a *huge* unrol=
led initializer, and will likely have an *extremely* long compilation time =
and high memory usage, if it doesn&#39;t crash your compiler outright. Plus=
 it&#39;s really awkward to use (you need function template or a class temp=
late partial specialization to unpack your sequence).</div><div><br></div><=
blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"ltr">While I am at it, I would al=
so like to propose constexpr function templates that return intialised arra=
ys, Specifically,<br><br>3.<br>a) return array of size N with each element =
initalised to a given C:<br>template &lt;typename T, size_t N, T C=3DT{}&gt=
;<br>constexpr auto make_filled_array()=C2=A0 -&gt; std::array&lt;T, N&gt;<=
br>{...}<br><br>b) return array of size N with each element intialised to a=
n integer in the given interval:<br>template &lt;typename T, T Cb, T Ce&gt;=
<br>constexpr auto make_array_spanning()<br>=C2=A0=C2=A0=C2=A0 -&gt; std::a=
rray&lt;T, detail_::span_count(Cb, Ce)&gt;<br>{...}<br><br>c) return array =
with elements initialised to a function applied to each element of the spec=
ified sequence:<br>template&lt;typename T, typename F, typename N, N... val=
ues&gt;=C2=A0=C2=A0=C2=A0 // F is aconstexpr callable with T F(N)<br>conste=
xpr auto eval_discrete_function(detail_::seq&lt;N, values...&gt; &amp;&amp;=
helper, F &amp;&amp;xf)<br>=C2=A0=C2=A0=C2=A0 -&gt; std::array&lt;T, sizeof=
....(values)&gt;<br>{=C2=A0 return {{xf(values)...}}; } // result_of&lt;F(N)=
::type should convert to T<br><br>and<br><br>template&lt;typename F, typena=
me N, N... values&gt;<br>constexpr auto eval_discrete_function(detail_::seq=
&lt;N, values...&gt; &amp;&amp;helper, F &amp;&amp;xf)<br>=C2=A0=C2=A0=C2=
=A0 -&gt; std::array&lt;typename std::result_of&lt;F(N)&gt;::type, sizeof..=
..(values)&gt;<br>{...}<br></div></blockquote><div><br></div><div>This seems=
 much more reasonable, and has the advantage that the compiler can in many =
cases choose to run the initializer at runtime if it&#39;s for a too-large =
array.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
">Please consider these suggestions, and let me know whether you can see en=
ough value in any of them to merit a fully-fledged proposal. While I have n=
o experience of writing proposals for additions to the standard, Daniel has=
 kindly offered to help me through the process.<br><br>Thank you.<span clas=
s=3D"HOEnZb"><font color=3D"#888888"><br><br></font></span></div><span clas=
s=3D"HOEnZb"><font color=3D"#888888">

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a1143f7987165d8052424cfe2--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Mon, 9 Nov 2015 17:18:16 -0800 (PST)
Raw View
------=_Part_7222_2127463149.1447118296605
Content-Type: multipart/alternative;
 boundary="----=_Part_7223_1409596874.1447118296605"

------=_Part_7223_1409596874.1447118296605
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Monday, November 9, 2015 at 12:59:50 PM UTC-8, Amit Jain wrote:
>
> Hello,
>
> I stumbled upon a limitation of std::make_integer_sequence<> template,=20
> while trying to make a statically intialised character conversion table. =
I=20
> have been in correspondence with Daniel Kr=C3=BCgler about ways to fix it=
; he=20
> encouraged me to post the problem and my proposed solution here.=20
>
> The problem:
> make_integer_sequence<typename T, T > can not make all possible contiguou=
s=20
> sequences of integers of type T. By design it excludes sequences containi=
ng=20
> negative integers (for signed T). Also, it can not make sequences=20
> containing all positive numbers for unsigned integers. Specifically,=20
> numeric_limits::max<T>() can not be part of a sequence made by=20
> make_integer_sequence<typename U, U> where U is an unsigned integral type=
..=20
> This is a consequence of the fact that U is used to encode the count N of=
=20
> elements in the resulting integer_sequence<0, 1, ..., N-1>.
>
> A generic fix for this is not possible because there is no type able to=
=20
> represent numeric_limits<uintmax_t>::max() + 1.
>
> After some thought, I think the best way forward is to have new make_*=20
> templates that provide functionality missing from make_integer_sequence. =
I=20
> am basing my suggestions on the assumption that the most common use of=20
> integer_sequence<> template is to construct intialiser lists, for=20
> aggregates, as well as containers.
>

+1 to what Richard said about template metaprogramming being a really poor=
=20
substitute for a two-line `for` loop.

I believe your assumption is faulty. IMO the purpose of=20
integer_sequence<class T, T...> is to make the architecture astronauts=20
happy by providing a "generic base" for index_sequence<size_t...>, and the=
=20
most common use of index_sequence<size_t...> is to temporarily hold a list=
=20
of indices for unpacking a tuple or typelist via something like

    template<typename Tuple, size_t... Idx>
    auto foo_helper(const Tuple& t, std::index_sequence<Idx...>) {
        return std::make_tuple(std::get<Idx>(t)...);
    }

For the specific problem mentioned above, I propose a new template,=20
> make_interval_sequence<typename T, T start, T end> to represent all=20
> integers in the closed interval [start, end].
>
[...]

> I propose another template, make_uniform_sequence<typename T, size_t N, T=
=20
> C> that would construct an integer_sequence<T, C, ..., C>.
>

It seems like a much more generic and fundamental primitive would be=20
something like

template<class Func, class T, T... Inputs>
auto sequence_apply(std::integer_sequence<T, Inputs...>)
{
    return std::integer_sequence<T, Func::apply(Inputs)...>{};
}

so that you could then implement

template<class T, T start, T end>
auto make_interval_sequence()
{
    class plus_start {
        static T apply(T in) { return in + start; }
    };
    return sequence_apply<plus_start>(std::make_integer_sequence<T, end -=
=20
start + 1>{});
}

and

template<class T, size_t N, T C>
auto make_uniform_sequence()
{
    class just_c {
        static T apply(size_t) { return C; }
    };
    return sequence_apply<just_c>(std::make_index_sequence<N>{});
}

My above suggestion clearly isn't ready for standardization (and in fact I=
=20
might already be missing a way to do it within the existing standard=20
library), but I would expect something along these "generic" lines would=20
stand a better chance of standardization than a bunch of special-case=20
aliases for use-cases that aren't actually very common to begin with. Also,=
=20
it would definitely be worthwhile for you to look into MPL/Hana/etc. (which=
=20
I personally have never used and don't know much about) if you're going to=
=20
be doing a lot of template metaprogramming.

=E2=80=93Arthur

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_7223_1409596874.1447118296605
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Monday, November 9, 2015 at 12:59:50 PM UTC-8, Amit Jain wrote:<blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Hello,<br><br>I stumbl=
ed upon a limitation of std::make_integer_sequence&lt;&gt; template, while =
trying to make a statically intialised character conversion table. I have b=
een in correspondence with Daniel Kr=C3=BCgler about ways to fix it; he enc=
ouraged me to post the problem and my proposed solution here. <br><br>The p=
roblem:<br>make_integer_sequence&lt;typename T, T &gt; can not make all pos=
sible contiguous sequences of integers of type T. By design it excludes seq=
uences containing negative integers (for signed T). Also, it can not make s=
equences containing all positive numbers for unsigned integers. Specificall=
y, numeric_limits::max&lt;T&gt;() can not be part of a sequence made by mak=
e_integer_sequence&lt;typename U, U&gt; where U is an unsigned integral typ=
e. This is a consequence of the fact that U is used to encode the count N o=
f elements in the resulting integer_sequence&lt;0, 1, ..., N-1&gt;.<br><br>=
A generic fix for this is not possible because there is no type able to rep=
resent numeric_limits&lt;uintmax_t&gt;::<wbr>max() + 1.<br><br>After some t=
hought, I think the best way forward is to have new make_*=20
templates that provide functionality missing from make_integer_sequence. I =
am basing my suggestions on the assumption that the most common use of inte=
ger_sequence&lt;&gt; template is to construct intialiser lists, for aggrega=
tes, as well as containers.<br></div></blockquote><div><br></div><div><div>=
+1 to what Richard said about template metaprogramming being a really poor =
substitute for a two-line `for` loop.</div><div><br></div></div><div>I beli=
eve your assumption is faulty. IMO the purpose of integer_sequence&lt;class=
 T, T...&gt; is to make the architecture astronauts happy by providing a &q=
uot;generic base&quot; for index_sequence&lt;size_t...&gt;, and the most co=
mmon use of index_sequence&lt;size_t...&gt; is to temporarily hold a list o=
f indices for unpacking a tuple or typelist via something like</div><div><b=
r></div><div>=C2=A0 =C2=A0 template&lt;typename Tuple, size_t... Idx&gt;</d=
iv><div>=C2=A0 =C2=A0 auto foo_helper(const Tuple&amp; t, std::index_sequen=
ce&lt;Idx...&gt;) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 return std::make_=
tuple(std::get&lt;Idx&gt;(t)...);</div><div>=C2=A0 =C2=A0 }</div><div><br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">For the =
specific problem mentioned above, I propose a new template, make_interval_s=
equence&lt;<wbr>typename T, T start, T end&gt; to represent all integers in=
 the closed interval [start, end].<br></div></blockquote><div>[...]</div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">I propose anoth=
er template, make_uniform_sequence&lt;typename T, size_t N, T C&gt; that wo=
uld construct an integer_sequence&lt;T, C, ..., C&gt;.<br></div></blockquot=
e><div><br></div><div>It seems like a much more generic and fundamental pri=
mitive would be something like</div><div><br></div><div>template&lt;class F=
unc, class T, T... Inputs&gt;</div><div>auto sequence_apply(std::integer_se=
quence&lt;T, Inputs...&gt;)</div><div>{</div><div>=C2=A0 =C2=A0 return std:=
:integer_sequence&lt;T, Func::apply(Inputs)...&gt;{};</div><div>}</div><div=
><br></div><div>so that you could then implement</div><div><br></div><div>t=
emplate&lt;class T, T start, T end&gt;</div><div>auto make_interval_sequenc=
e()<br></div><div>{</div><div>=C2=A0 =C2=A0 class plus_start {</div><div>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 static T apply(T in) { return in + start; }</di=
v><div>=C2=A0 =C2=A0 };</div><div>=C2=A0 =C2=A0 return sequence_apply&lt;pl=
us_start&gt;(std::make_integer_sequence&lt;T, end - start + 1&gt;{});</div>=
<div>}</div><div><br></div><div>and</div><div><br></div><div>template&lt;cl=
ass T, size_t N, T C&gt;<br></div><div>auto make_uniform_sequence()</div><d=
iv>{</div><div><div>=C2=A0 =C2=A0 class just_c {</div><div>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 static T apply(size_t) { return C; }</div><div>=C2=A0 =C2=A0 =
};</div><div>=C2=A0 =C2=A0 return sequence_apply&lt;just_c&gt;(std::make_in=
dex_sequence&lt;N&gt;{});</div></div><div>}</div><div><br></div><div>My abo=
ve suggestion clearly isn&#39;t ready for standardization (and in fact I mi=
ght already be missing a way to do it within the existing standard library)=
, but I would expect something along these &quot;generic&quot; lines would =
stand a better chance of standardization than a bunch of special-case alias=
es for use-cases that aren&#39;t actually very common to begin with. Also, =
it would definitely be worthwhile for you to look into MPL/Hana/etc. (which=
 I personally have never used and don&#39;t know much about) if you&#39;re =
going to be doing a lot of template metaprogramming.</div><div><br></div><d=
iv>=E2=80=93Arthur<br></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_7223_1409596874.1447118296605--
------=_Part_7222_2127463149.1447118296605--

.


Author: Amit Jain <amit.jain@sbgenomics.com>
Date: Tue, 10 Nov 2015 11:31:36 -0800 (PST)
Raw View
------=_Part_5537_1204337851.1447183896457
Content-Type: multipart/alternative;
 boundary="----=_Part_5538_1923621222.1447183896458"

------=_Part_5538_1923621222.1447183896458
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Tuesday, November 10, 2015 at 12:30:03 AM UTC, Richard Smith wrote:
>
> On Mon, Nov 9, 2015 at 12:59 PM, Amit Jain <amit...@sbgenomics.com=20
> <javascript:>> wrote:
>
>> Hello,
>>
>> I stumbled upon a limitation of std::make_integer_sequence<> template,=
=20
>> while trying to make a statically intialised character conversion table.=
 I=20
>> have been in correspondence with Daniel Kr=C3=BCgler about ways to fix i=
t; he=20
>> encouraged me to post the problem and my proposed solution here.=20
>>
>> The problem:
>> make_integer_sequence<typename T, T > can not make all possible=20
>> contiguous sequences of integers of type T. By design it excludes sequen=
ces=20
>> containing negative integers (for signed T). Also, it can not make=20
>> sequences containing all positive numbers for unsigned integers.=20
>> Specifically, numeric_limits::max<T>() can not be part of a sequence mad=
e=20
>> by make_integer_sequence<typename U, U> where U is an unsigned integral=
=20
>> type. This is a consequence of the fact that U is used to encode the cou=
nt=20
>> N of elements in the resulting integer_sequence<0, 1, ..., N-1>.
>>
>> A generic fix for this is not possible because there is no type able to=
=20
>> represent numeric_limits<uintmax_t>::max() + 1.
>>
>
> So what? No compiler will be able to expand a pack with that many element=
s.
>

This much is evident. However, where do you draw the line? Should it be=20
possible to make an integer_sequence<uint8_t, 0, 1, ..., UINT8_MAX>? How=20
about uint16_t? My first thought was that a simple change would suffice:=20
make_integer_sequence<typename T, size_t N> - but Daniel pointed out that=
=20
this would still be broken for size_t.
=20

> =20
>
>> After some thought, I think the best way forward is to have new make_*=
=20
>> templates that provide functionality missing from make_integer_sequence.=
 I=20
>> am basing my suggestions on the assumption that the most common use of=
=20
>> integer_sequence<> template is to construct intialiser lists, for=20
>> aggregates, as well as containers.
>>
>> (I have C++14 compliant implementations available for all of the=20
>> proposals)
>>
>> 1.
>> For the specific problem mentioned above, I propose a new template,=20
>> make_interval_sequence<typename T, T start, T end> to represent all=20
>> integers in the closed interval [start, end]. There is no requirement th=
at=20
>> start be less than end. This can represent all possible contiguous=20
>> sequences. It cannot be used to create an empty sequence.
>>
>
> Using a closed interval here is not a good match for the usual C++ model=
=20
> of half-open ranges.
>
> But this proposal is to get around the specific problem with half open=20
ranges: that the type of the integer elements in the range is in general=20
not wide enough to specify the open limit of the range.
 =20

> 2.
>> I propose another template, make_uniform_sequence<typename T, size_t N, =
T=20
>> C> that would construct an integer_sequence<T, C, ..., C>. This would be=
=20
>> useful for initialising T[] and std::array<T, N> to a given value. I=20
>> believe this would prevent many many programmers having to reinvent this=
=20
>> idiom.
>>
>
> This seems like a potentially disastrous thing to encourage. Compare:
>
>   T x[1000000];
>   for (auto &v : x) { v =3D C; }
>
> versus
>
>   T x[1000000] =3D { pack_of_1000000_Cs ...};
>
> The former will emit a small loop, and the compiler is likely to turn it=
=20
> into memset or similar. The latter will emit (and create an AST or simila=
r=20
> for) a *huge* unrolled initializer, and will likely have an *extremely*=
=20
> long compilation time and high memory usage, if it doesn't crash your=20
> compiler outright. Plus it's really awkward to use (you need function=20
> template or a class template partial specialization to unpack your=20
> sequence).
>
> This I agree with. Motivation behind this construct was to introduce the=
=20
intialising functions below. I now see how they can be implemented without=
=20
needing the compile-time sequence type.
=20

> While I am at it, I would also like to propose constexpr function=20
>> templates that return intialised arrays, Specifically,
>>
>> 3.
>> a) return array of size N with each element initalised to a given C:
>> template <typename T, size_t N, T C=3DT{}>
>> constexpr auto make_filled_array()  -> std::array<T, N>
>> {...}
>>
>> b) return array of size N with each element intialised to an integer in=
=20
>> the given interval:
>> template <typename T, T Cb, T Ce>
>> constexpr auto make_array_spanning()
>>     -> std::array<T, detail_::span_count(Cb, Ce)>
>> {...}
>>
>> c) return array with elements initialised to a function applied to each=
=20
>> element of the specified sequence:
>> template<typename T, typename F, typename N, N... values>    // F is=20
>> aconstexpr callable with T F(N)
>> constexpr auto eval_discrete_function(detail_::seq<N, values...>=20
>> &&helper, F &&xf)
>>     -> std::array<T, sizeof...(values)>
>> {  return {{xf(values)...}}; } // result_of<F(N)::type should convert to=
 T
>>
>> and
>>
>> template<typename F, typename N, N... values>
>> constexpr auto eval_discrete_function(detail_::seq<N, values...>=20
>> &&helper, F &&xf)
>>     -> std::array<typename std::result_of<F(N)>::type, sizeof...(values)=
>
>> {...}
>>
>
> This seems much more reasonable, and has the advantage that the compiler=
=20
> can in many cases choose to run the initializer at runtime if it's for a=
=20
> too-large array.
> =20
>
Thanks.=20

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_5538_1923621222.1447183896458
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Tuesday, November 10, 2015 at 12:30:03 AM UTC, Richard Smith wro=
te:<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><div =
class=3D"gmail_quote">On Mon, Nov 9, 2015 at 12:59 PM, Amit Jain <span dir=
=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"nf-f8J-0FgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascr=
ipt:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return=
 true;">amit...@sbgenomics.com</a>&gt;</span> wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">Hello,<br><br>I stumbled upon a limitation o=
f std::make_integer_sequence&lt;&gt; template, while trying to make a stati=
cally intialised character conversion table. I have been in correspondence =
with Daniel Kr=C3=BCgler about ways to fix it; he encouraged me to post the=
 problem and my proposed solution here. <br><br>The problem:<br>make_intege=
r_sequence&lt;typename T, T &gt; can not make all possible contiguous seque=
nces of integers of type T. By design it excludes sequences containing nega=
tive integers (for signed T). Also, it can not make sequences containing al=
l positive numbers for unsigned integers. Specifically, numeric_limits::max=
&lt;T&gt;() can not be part of a sequence made by make_integer_sequence&lt;=
typename U, U&gt; where U is an unsigned integral type. This is a consequen=
ce of the fact that U is used to encode the count N of elements in the resu=
lting integer_sequence&lt;0, 1, ..., N-1&gt;.<br><br>A generic fix for this=
 is not possible because there is no type able to represent numeric_limits&=
lt;uintmax_t&gt;::<wbr>max() + 1.<br></div></blockquote><div><br></div><div=
>So what? No compiler will be able to expand a pack with that many elements=
..</div></div></div></div></blockquote><div><br>This much is evident. Howeve=
r, where do you draw the line? Should it be possible to make an integer_seq=
uence&lt;uint8_t, 0, 1, ..., UINT8_MAX&gt;? How about uint16_t? My first th=
ought was that a simple change would suffice: make_integer_sequence&lt;type=
name T, size_t N&gt; - but Daniel pointed out that this would still be brok=
en for size_t.<br>=C2=A0<br></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><div class=3D"gmail_quote"><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr">After some thought, I think th=
e best way forward is to have new make_*=20
templates that provide functionality missing from make_integer_sequence. I =
am basing my suggestions on the assumption that the most common use of inte=
ger_sequence&lt;&gt; template is to construct intialiser lists, for aggrega=
tes, as well as containers.<br><br>(I have C++14 compliant implementations =
available for all of the proposals)<br><br>1.<br>For the specific problem m=
entioned above, I propose a new template, make_interval_sequence&lt;<wbr>ty=
pename T, T start, T end&gt; to represent all integers in the closed interv=
al [start, end]. There is no requirement that start be less than end. This =
can represent all possible contiguous sequences. It cannot be used to creat=
e an empty sequence.<br></div></blockquote><div><br></div><div>Using a clos=
ed interval here is not a good match for the usual C++ model of half-open r=
anges.</div><div><br></div></div></div></div></blockquote><div>But this pro=
posal is to get around the specific problem with half open ranges: that the=
 type of the integer elements in the range is in general not wide enough to=
 specify the open limit of the range.<br>=C2=A0 <br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote=
"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">2.<br>I propos=
e another template, make_uniform_sequence&lt;typename T, size_t N, T C&gt; =
that would construct an integer_sequence&lt;T, C, ..., C&gt;. This would be=
 useful for initialising T[] and std::array&lt;T, N&gt; to a given value. I=
 believe this would prevent many many programmers having to reinvent this i=
diom.<br></div></blockquote><div><br></div><div>This seems like a potential=
ly disastrous thing to encourage. Compare:</div><div><br></div><div>=C2=A0 =
T x[1000000];</div><div>=C2=A0 for (auto &amp;v : x) { v =3D C; }</div><div=
><br></div><div>versus</div><div><br></div><div>=C2=A0 T x[1000000] =3D { p=
ack_of_1000000_Cs ...};</div><div><br></div><div>The former will emit a sma=
ll loop, and the compiler is likely to turn it into memset or similar. The =
latter will emit (and create an AST or similar for) a *huge* unrolled initi=
alizer, and will likely have an *extremely* long compilation time and high =
memory usage, if it doesn&#39;t crash your compiler outright. Plus it&#39;s=
 really awkward to use (you need function template or a class template part=
ial specialization to unpack your sequence).</div><div><br></div></div></di=
v></div></blockquote><div>This I agree with. Motivation behind this constru=
ct was to introduce the intialising functions below. I now see how they can=
 be implemented without needing the compile-time sequence type.<br>=C2=A0<b=
r></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>=
<div class=3D"gmail_quote"><div></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr">While I am at it, I would also like to propose constexpr functio=
n templates that return intialised arrays, Specifically,<br><br>3.<br>a) re=
turn array of size N with each element initalised to a given C:<br>template=
 &lt;typename T, size_t N, T C=3DT{}&gt;<br>constexpr auto make_filled_arra=
y()=C2=A0 -&gt; std::array&lt;T, N&gt;<br>{...}<br><br>b) return array of s=
ize N with each element intialised to an integer in the given interval:<br>=
template &lt;typename T, T Cb, T Ce&gt;<br>constexpr auto make_array_spanni=
ng()<br>=C2=A0=C2=A0=C2=A0 -&gt; std::array&lt;T, detail_::span_count(Cb, C=
e)&gt;<br>{...}<br><br>c) return array with elements initialised to a funct=
ion applied to each element of the specified sequence:<br>template&lt;typen=
ame T, typename F, typename N, N... values&gt;=C2=A0=C2=A0=C2=A0 // F is ac=
onstexpr callable with T F(N)<br>constexpr auto eval_discrete_function(deta=
il_<wbr>::seq&lt;N, values...&gt; &amp;&amp;helper, F &amp;&amp;xf)<br>=C2=
=A0=C2=A0=C2=A0 -&gt; std::array&lt;T, sizeof...(values)&gt;<br>{=C2=A0 ret=
urn {{xf(values)...}}; } // result_of&lt;F(N)::type should convert to T<br>=
<br>and<br><br>template&lt;typename F, typename N, N... values&gt;<br>const=
expr auto eval_discrete_function(detail_<wbr>::seq&lt;N, values...&gt; &amp=
;&amp;helper, F &amp;&amp;xf)<br>=C2=A0=C2=A0=C2=A0 -&gt; std::array&lt;typ=
ename std::result_of&lt;F(N)&gt;::type, sizeof...(values)&gt;<br>{...}<br><=
/div></blockquote><div><br></div><div>This seems much more reasonable, and =
has the advantage that the compiler can in many cases choose to run the ini=
tializer at runtime if it&#39;s for a too-large array.</div><div>=C2=A0</di=
v></div></div></div></blockquote><div>Thanks. <br></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_5538_1923621222.1447183896458--
------=_Part_5537_1204337851.1447183896457--

.


Author: Amit Jain <amit.jain@sbgenomics.com>
Date: Tue, 10 Nov 2015 11:53:17 -0800 (PST)
Raw View
------=_Part_3946_1139176110.1447185197924
Content-Type: multipart/alternative;
 boundary="----=_Part_3947_759731703.1447185197924"

------=_Part_3947_759731703.1447185197924
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Tuesday, November 10, 2015 at 1:18:16 AM UTC, Arthur O'Dwyer wrote:
>
> On Monday, November 9, 2015 at 12:59:50 PM UTC-8, Amit Jain wrote:
>>
>> Hello,
>>
>> I stumbled upon a limitation of std::make_integer_sequence<> template,=
=20
>> while trying to make a statically intialised character conversion table.=
 I=20
>> have been in correspondence with Daniel Kr=C3=BCgler about ways to fix i=
t; he=20
>> encouraged me to post the problem and my proposed solution here.=20
>>
>> The problem:
>> make_integer_sequence<typename T, T > can not make all possible=20
>> contiguous sequences of integers of type T. By design it excludes sequen=
ces=20
>> containing negative integers (for signed T). Also, it can not make=20
>> sequences containing all positive numbers for unsigned integers.=20
>> Specifically, numeric_limits::max<T>() can not be part of a sequence mad=
e=20
>> by make_integer_sequence<typename U, U> where U is an unsigned integral=
=20
>> type. This is a consequence of the fact that U is used to encode the cou=
nt=20
>> N of elements in the resulting integer_sequence<0, 1, ..., N-1>.
>>
>> A generic fix for this is not possible because there is no type able to=
=20
>> represent numeric_limits<uintmax_t>::max() + 1.
>>
>> After some thought, I think the best way forward is to have new make_*=
=20
>> templates that provide functionality missing from make_integer_sequence.=
 I=20
>> am basing my suggestions on the assumption that the most common use of=
=20
>> integer_sequence<> template is to construct intialiser lists, for=20
>> aggregates, as well as containers.
>>
>
> +1 to what Richard said about template metaprogramming being a really poo=
r=20
> substitute for a two-line `for` loop.
>
> Horses for courses, no? TMP is good for declaring small immutable=20
structures (my use case in this instance).
=20

> I believe your assumption is faulty. IMO the purpose of=20
> integer_sequence<class T, T...> is to make the architecture astronauts=20
> happy by providing a "generic base" for index_sequence<size_t...>, and th=
e=20
> most common use of index_sequence<size_t...> is to temporarily hold a lis=
t=20
> of indices for unpacking a tuple or typelist via something like
>
>     template<typename Tuple, size_t... Idx>
>     auto foo_helper(const Tuple& t, std::index_sequence<Idx...>) {
>         return std::make_tuple(std::get<Idx>(t)...);
>     }
>
> OK.

For the specific problem mentioned above, I propose a new template,=20
>> make_interval_sequence<typename T, T start, T end> to represent all=20
>> integers in the closed interval [start, end].
>>
> [...]
>
>> I propose another template, make_uniform_sequence<typename T, size_t N, =
T=20
>> C> that would construct an integer_sequence<T, C, ..., C>.
>>
>
> It seems like a much more generic and fundamental primitive would be=20
> something like
>
> template<class Func, class T, T... Inputs>
> auto sequence_apply(std::integer_sequence<T, Inputs...>)
> {
>     return std::integer_sequence<T, Func::apply(Inputs)...>{};
> }
>
> I think this is great! Though I would prefer=20
sequence_apply(integer_sequence<T, T...> in =3D ...{}, Func &&f =3D Func{})
Then this transformer could be used at runtime also with lambdas etc.
=20

> so that you could then implement
>
> template<class T, T start, T end>
> auto make_interval_sequence()
> {
>     class plus_start {
>         static T apply(T in) { return in + start; }
>     };
>     return sequence_apply<plus_start>(std::make_integer_sequence<T, end -=
=20
> start + 1>{});
> }
>

In principle, yes. Though I would want to relax the assumption that start=
=20
<=3D end.
=20

>
> and
>
> template<class T, size_t N, T C>
> auto make_uniform_sequence()
> {
>     class just_c {
>         static T apply(size_t) { return C; }
>     };
>     return sequence_apply<just_c>(std::make_index_sequence<N>{});
> }
>
> My above suggestion clearly isn't ready for standardization (and in fact =
I=20
> might already be missing a way to do it within the existing standard=20
> library), but I would expect something along these "generic" lines would=
=20
> stand a better chance of standardization than a bunch of special-case=20
> aliases for use-cases that aren't actually very common to begin with. Als=
o,=20
> it would definitely be worthwhile for you to look into MPL/Hana/etc. (whi=
ch=20
> I personally have never used and don't know much about) if you're going t=
o=20
> be doing a lot of template metaprogramming.
>

MPL libraries aside, I think it would be very useful to have a compile-time=
=20
analog of std::transform(). I do hope we get some more opinions on this.=20

>
> =E2=80=93Arthur
>

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_3947_759731703.1447185197924
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<br><br>On Tuesday, November 10, 2015 at 1:18:16 AM UTC, Arthur O&#39;Dwyer=
 wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Monday, November 9, =
2015 at 12:59:50 PM UTC-8, Amit Jain wrote:<blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr">Hello,<br><br>I stumbled upon a limitation of std:=
:make_integer_sequence&lt;&gt; template, while trying to make a statically =
intialised character conversion table. I have been in correspondence with D=
aniel Kr=C3=BCgler about ways to fix it; he encouraged me to post the probl=
em and my proposed solution here. <br><br>The problem:<br>make_integer_sequ=
ence&lt;typename T, T &gt; can not make all possible contiguous sequences o=
f integers of type T. By design it excludes sequences containing negative i=
ntegers (for signed T). Also, it can not make sequences containing all posi=
tive numbers for unsigned integers. Specifically, numeric_limits::max&lt;T&=
gt;() can not be part of a sequence made by make_integer_sequence&lt;typena=
me U, U&gt; where U is an unsigned integral type. This is a consequence of =
the fact that U is used to encode the count N of elements in the resulting =
integer_sequence&lt;0, 1, ..., N-1&gt;.<br><br>A generic fix for this is no=
t possible because there is no type able to represent numeric_limits&lt;uin=
tmax_t&gt;::<wbr>max() + 1.<br><br>After some thought, I think the best way=
 forward is to have new make_*=20
templates that provide functionality missing from make_integer_sequence. I =
am basing my suggestions on the assumption that the most common use of inte=
ger_sequence&lt;&gt; template is to construct intialiser lists, for aggrega=
tes, as well as containers.<br></div></blockquote><div><br></div><div><div>=
+1 to what Richard said about template metaprogramming being a really poor =
substitute for a two-line `for` loop.</div><div><br></div></div></blockquot=
e><div>Horses for courses, no? TMP is good for declaring small immutable st=
ructures (my use case in this instance).<br>=C2=A0<br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div><div></div></div><div>I believe your ass=
umption is faulty. IMO the purpose of integer_sequence&lt;class T, T...&gt;=
 is to make the architecture astronauts happy by providing a &quot;generic =
base&quot; for index_sequence&lt;size_t...&gt;, and the most common use of =
index_sequence&lt;size_t...&gt; is to temporarily hold a list of indices fo=
r unpacking a tuple or typelist via something like</div><div><br></div><div=
>=C2=A0 =C2=A0 template&lt;typename Tuple, size_t... Idx&gt;</div><div>=C2=
=A0 =C2=A0 auto foo_helper(const Tuple&amp; t, std::index_sequence&lt;Idx..=
..&gt;) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 return std::make_tuple(std::=
get&lt;Idx&gt;(<wbr>t)...);</div><div>=C2=A0 =C2=A0 }</div><div><br></div><=
/blockquote><div>OK.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><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">F=
or the specific problem mentioned above, I propose a new template, make_int=
erval_sequence&lt;<wbr>typename T, T start, T end&gt; to represent all inte=
gers in the closed interval [start, end].<br></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">I propose ano=
ther template, make_uniform_sequence&lt;typename T, size_t N, T C&gt; that =
would construct an integer_sequence&lt;T, C, ..., C&gt;.<br></div></blockqu=
ote><div><br></div><div>It seems like a much more generic and fundamental p=
rimitive would be something like</div><div><br></div><div>template&lt;class=
 Func, class T, T... Inputs&gt;</div><div>auto sequence_apply(std::integer_=
<wbr>sequence&lt;T, Inputs...&gt;)</div><div>{</div><div>=C2=A0 =C2=A0 retu=
rn std::integer_sequence&lt;T, Func::apply(Inputs)...&gt;{};</div><div>}</d=
iv><div><br></div></blockquote><div>I think this is great! Though I would p=
refer sequence_apply(integer_sequence&lt;T, T...&gt; in =3D ...{}, Func &am=
p;&amp;f =3D Func{})<br>Then this transformer could be used at runtime also=
 with lambdas etc.<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div></div><div>so that you could then implement</div><div><br></di=
v><div>template&lt;class T, T start, T end&gt;</div><div>auto make_interval=
_sequence()<br></div><div>{</div><div>=C2=A0 =C2=A0 class plus_start {</div=
><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 static T apply(T in) { return in + start;=
 }</div><div>=C2=A0 =C2=A0 };</div><div>=C2=A0 =C2=A0 return sequence_apply=
&lt;plus_start&gt;(<wbr>std::make_integer_sequence&lt;T, end - start + 1&gt=
;{});</div><div>}</div></blockquote><div><br>In principle, yes. Though I wo=
uld want to relax the assumption that start &lt;=3D end.<br>=C2=A0<br></div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div><br></div><div>and</div>=
<div><br></div><div>template&lt;class T, size_t N, T C&gt;<br></div><div>au=
to make_uniform_sequence()</div><div>{</div><div><div>=C2=A0 =C2=A0 class j=
ust_c {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 static T apply(size_t) { retu=
rn C; }</div><div>=C2=A0 =C2=A0 };</div><div>=C2=A0 =C2=A0 return sequence_=
apply&lt;just_c&gt;(std::<wbr>make_index_sequence&lt;N&gt;{});</div></div><=
div>}</div><div><br></div><div>My above suggestion clearly isn&#39;t ready =
for standardization (and in fact I might already be missing a way to do it =
within the existing standard library), but I would expect something along t=
hese &quot;generic&quot; lines would stand a better chance of standardizati=
on than a bunch of special-case aliases for use-cases that aren&#39;t actua=
lly very common to begin with. Also, it would definitely be worthwhile for =
you to look into MPL/Hana/etc. (which I personally have never used and don&=
#39;t know much about) if you&#39;re going to be doing a lot of template me=
taprogramming.</div></blockquote><div><br>MPL libraries aside, I think it w=
ould be very useful to have a compile-time analog of std::transform(). I do=
 hope we get some more opinions on this. <br></div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid=
;padding-left: 1ex;"><div><br></div><div>=E2=80=93Arthur<br></div></blockqu=
ote>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_3947_759731703.1447185197924--
------=_Part_3946_1139176110.1447185197924--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Tue, 10 Nov 2015 11:53:28 -0800
Raw View
--94eb2c0807be414e5a05243510e3
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tue, Nov 10, 2015 at 11:31 AM, Amit Jain <amit.jain@sbgenomics.com>
wrote:

> On Tuesday, November 10, 2015 at 12:30:03 AM UTC, Richard Smith wrote:
>>
>> On Mon, Nov 9, 2015 at 12:59 PM, Amit Jain <amit...@sbgenomics.com>
>> wrote:
>>
>>> Hello,
>>>
>>> I stumbled upon a limitation of std::make_integer_sequence<> template,
>>> while trying to make a statically intialised character conversion table=
.. I
>>> have been in correspondence with Daniel Kr=C3=BCgler about ways to fix =
it; he
>>> encouraged me to post the problem and my proposed solution here.
>>>
>>> The problem:
>>> make_integer_sequence<typename T, T > can not make all possible
>>> contiguous sequences of integers of type T. By design it excludes seque=
nces
>>> containing negative integers (for signed T). Also, it can not make
>>> sequences containing all positive numbers for unsigned integers.
>>> Specifically, numeric_limits::max<T>() can not be part of a sequence ma=
de
>>> by make_integer_sequence<typename U, U> where U is an unsigned integral
>>> type. This is a consequence of the fact that U is used to encode the co=
unt
>>> N of elements in the resulting integer_sequence<0, 1, ..., N-1>.
>>>
>>> A generic fix for this is not possible because there is no type able to
>>> represent numeric_limits<uintmax_t>::max() + 1.
>>>
>>
>> So what? No compiler will be able to expand a pack with that many
>> elements.
>>
>
> This much is evident. However, where do you draw the line? Should it be
> possible to make an integer_sequence<uint8_t, 0, 1, ..., UINT8_MAX>? How
> about uint16_t? My first thought was that a simple change would suffice:
> make_integer_sequence<typename T, size_t N> - but Daniel pointed out that
> this would still be broken for size_t.
>

My take:
 * Fixing this for T=3Duint8_t (and for bool) might be useful to some. Fixi=
ng
it for T=3Dsize_t serves no purpose.
 * At least one implementation (libc++) effectively already does this, and
only uses T (instead of size_t) as the type of N at the outermost layer;
this allows more reuse of already-computed sequences.
 * The narrowing conversion check is different: with this change we would
start to properly diagnose the case where N is negative for a signed T, but
we would also allow N > max value of T + 1, leading to the elements being
repeated multiple times (which may actually be a feature depending on what
the user intended)

Overall, I think I'd be weakly in favour of changing the type of N from T
to size_t. I think this is worth suggesting to LEWG.

After some thought, I think the best way forward is to have new make_*
>>> templates that provide functionality missing from make_integer_sequence=
.. I
>>> am basing my suggestions on the assumption that the most common use of
>>> integer_sequence<> template is to construct intialiser lists, for
>>> aggregates, as well as containers.
>>>
>>> (I have C++14 compliant implementations available for all of the
>>> proposals)
>>>
>>> 1.
>>> For the specific problem mentioned above, I propose a new template,
>>> make_interval_sequence<typename T, T start, T end> to represent all
>>> integers in the closed interval [start, end]. There is no requirement t=
hat
>>> start be less than end. This can represent all possible contiguous
>>> sequences. It cannot be used to create an empty sequence.
>>>
>>
>> Using a closed interval here is not a good match for the usual C++ model
>> of half-open ranges.
>>
>> But this proposal is to get around the specific problem with half open
> ranges: that the type of the integer elements in the range is in general
> not wide enough to specify the open limit of the range.
>
>
>> 2.
>>> I propose another template, make_uniform_sequence<typename T, size_t N,
>>> T C> that would construct an integer_sequence<T, C, ..., C>. This would=
 be
>>> useful for initialising T[] and std::array<T, N> to a given value. I
>>> believe this would prevent many many programmers having to reinvent thi=
s
>>> idiom.
>>>
>>
>> This seems like a potentially disastrous thing to encourage. Compare:
>>
>>   T x[1000000];
>>   for (auto &v : x) { v =3D C; }
>>
>> versus
>>
>>   T x[1000000] =3D { pack_of_1000000_Cs ...};
>>
>> The former will emit a small loop, and the compiler is likely to turn it
>> into memset or similar. The latter will emit (and create an AST or simil=
ar
>> for) a *huge* unrolled initializer, and will likely have an *extremely*
>> long compilation time and high memory usage, if it doesn't crash your
>> compiler outright. Plus it's really awkward to use (you need function
>> template or a class template partial specialization to unpack your
>> sequence).
>>
>> This I agree with. Motivation behind this construct was to introduce the
> intialising functions below. I now see how they can be implemented withou=
t
> needing the compile-time sequence type.
>
>
>> While I am at it, I would also like to propose constexpr function
>>> templates that return intialised arrays, Specifically,
>>>
>>> 3.
>>> a) return array of size N with each element initalised to a given C:
>>> template <typename T, size_t N, T C=3DT{}>
>>> constexpr auto make_filled_array()  -> std::array<T, N>
>>> {...}
>>>
>>> b) return array of size N with each element intialised to an integer in
>>> the given interval:
>>> template <typename T, T Cb, T Ce>
>>> constexpr auto make_array_spanning()
>>>     -> std::array<T, detail_::span_count(Cb, Ce)>
>>> {...}
>>>
>>> c) return array with elements initialised to a function applied to each
>>> element of the specified sequence:
>>> template<typename T, typename F, typename N, N... values>    // F is
>>> aconstexpr callable with T F(N)
>>> constexpr auto eval_discrete_function(detail_::seq<N, values...>
>>> &&helper, F &&xf)
>>>     -> std::array<T, sizeof...(values)>
>>> {  return {{xf(values)...}}; } // result_of<F(N)::type should convert t=
o
>>> T
>>>
>>> and
>>>
>>> template<typename F, typename N, N... values>
>>> constexpr auto eval_discrete_function(detail_::seq<N, values...>
>>> &&helper, F &&xf)
>>>     -> std::array<typename std::result_of<F(N)>::type, sizeof...(values=
)>
>>> {...}
>>>
>>
>> This seems much more reasonable, and has the advantage that the compiler
>> can in many cases choose to run the initializer at runtime if it's for a
>> too-large array.
>>
>>
> Thanks.
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--=20

---=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--94eb2c0807be414e5a05243510e3
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
ue, Nov 10, 2015 at 11:31 AM, Amit Jain <span dir=3D"ltr">&lt;<a href=3D"ma=
ilto:amit.jain@sbgenomics.com" target=3D"_blank">amit.jain@sbgenomics.com</=
a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0=
 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tuesday, November=
 10, 2015 at 12:30:03 AM UTC, Richard Smith wrote:<span class=3D""><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_q=
uote">On Mon, Nov 9, 2015 at 12:59 PM, Amit Jain <span dir=3D"ltr">&lt;<a r=
el=3D"nofollow">amit...@sbgenomics.com</a>&gt;</span> wrote:<br><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr">Hello,<br><br>I stumbled upon a limita=
tion of std::make_integer_sequence&lt;&gt; template, while trying to make a=
 statically intialised character conversion table. I have been in correspon=
dence with Daniel Kr=C3=BCgler about ways to fix it; he encouraged me to po=
st the problem and my proposed solution here. <br><br>The problem:<br>make_=
integer_sequence&lt;typename T, T &gt; can not make all possible contiguous=
 sequences of integers of type T. By design it excludes sequences containin=
g negative integers (for signed T). Also, it can not make sequences contain=
ing all positive numbers for unsigned integers. Specifically, numeric_limit=
s::max&lt;T&gt;() can not be part of a sequence made by make_integer_sequen=
ce&lt;typename U, U&gt; where U is an unsigned integral type. This is a con=
sequence of the fact that U is used to encode the count N of elements in th=
e resulting integer_sequence&lt;0, 1, ..., N-1&gt;.<br><br>A generic fix fo=
r this is not possible because there is no type able to represent numeric_l=
imits&lt;uintmax_t&gt;::max() + 1.<br></div></blockquote><div><br></div><di=
v>So what? No compiler will be able to expand a pack with that many element=
s.</div></div></div></div></blockquote></span><div><br>This much is evident=
.. However, where do you draw the line? Should it be possible to make an int=
eger_sequence&lt;uint8_t, 0, 1, ..., UINT8_MAX&gt;? How about uint16_t? My =
first thought was that a simple change would suffice: make_integer_sequence=
&lt;typename T, size_t N&gt; - but Daniel pointed out that this would still=
 be broken for size_t.</div></blockquote><div><br></div><div>My take:</div>=
<div>=C2=A0* Fixing this for T=3Duint8_t (and for bool) might be useful to =
some. Fixing it for T=3Dsize_t serves no purpose.</div><div>=C2=A0* At leas=
t one implementation (libc++) effectively already does this, and only uses =
T (instead of size_t) as the type of N at the outermost layer; this allows =
more reuse of already-computed sequences.</div><div>=C2=A0* The narrowing c=
onversion check is different: with this change we would start to properly d=
iagnose the case where N is negative for a signed T, but we would also allo=
w N &gt; max value of T + 1, leading to the elements being repeated multipl=
e times (which may actually be a feature depending on what the user intende=
d)</div><div><br></div><div>Overall, I think I&#39;d be weakly in favour of=
 changing the type of N from T to size_t. I think this is worth suggesting =
to LEWG.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"=
"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"gm=
ail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">After some thoug=
ht, I think the best way forward is to have new make_*=20
templates that provide functionality missing from make_integer_sequence. I =
am basing my suggestions on the assumption that the most common use of inte=
ger_sequence&lt;&gt; template is to construct intialiser lists, for aggrega=
tes, as well as containers.<br><br>(I have C++14 compliant implementations =
available for all of the proposals)<br><br>1.<br>For the specific problem m=
entioned above, I propose a new template, make_interval_sequence&lt;typenam=
e T, T start, T end&gt; to represent all integers in the closed interval [s=
tart, end]. There is no requirement that start be less than end. This can r=
epresent all possible contiguous sequences. It cannot be used to create an =
empty sequence.<br></div></blockquote><div><br></div><div>Using a closed in=
terval here is not a good match for the usual C++ model of half-open ranges=
..</div><div><br></div></div></div></blockquote></span><div>But this proposa=
l is to get around the specific problem with half open ranges: that the typ=
e of the integer elements in the range is in general not wide enough to spe=
cify the open limit of the range.<br>=C2=A0 <br></div><span class=3D""><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gma=
il_quote"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">2.<br>=
I propose another template, make_uniform_sequence&lt;typename T, size_t N, =
T C&gt; that would construct an integer_sequence&lt;T, C, ..., C&gt;. This =
would be useful for initialising T[] and std::array&lt;T, N&gt; to a given =
value. I believe this would prevent many many programmers having to reinven=
t this idiom.<br></div></blockquote><div><br></div><div>This seems like a p=
otentially disastrous thing to encourage. Compare:</div><div><br></div><div=
>=C2=A0 T x[1000000];</div><div>=C2=A0 for (auto &amp;v : x) { v =3D C; }</=
div><div><br></div><div>versus</div><div><br></div><div>=C2=A0 T x[1000000]=
 =3D { pack_of_1000000_Cs ...};</div><div><br></div><div>The former will em=
it a small loop, and the compiler is likely to turn it into memset or simil=
ar. The latter will emit (and create an AST or similar for) a *huge* unroll=
ed initializer, and will likely have an *extremely* long compilation time a=
nd high memory usage, if it doesn&#39;t crash your compiler outright. Plus =
it&#39;s really awkward to use (you need function template or a class templ=
ate partial specialization to unpack your sequence).</div><div><br></div></=
div></div></div></blockquote></span><div>This I agree with. Motivation behi=
nd this construct was to introduce the intialising functions below. I now s=
ee how they can be implemented without needing the compile-time sequence ty=
pe.<br>=C2=A0<br></div><span class=3D""><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex"><div dir=3D"ltr">While I am at it, I would also like t=
o propose constexpr function templates that return intialised arrays, Speci=
fically,<br><br>3.<br>a) return array of size N with each element initalise=
d to a given C:<br>template &lt;typename T, size_t N, T C=3DT{}&gt;<br>cons=
texpr auto make_filled_array()=C2=A0 -&gt; std::array&lt;T, N&gt;<br>{...}<=
br><br>b) return array of size N with each element intialised to an integer=
 in the given interval:<br>template &lt;typename T, T Cb, T Ce&gt;<br>const=
expr auto make_array_spanning()<br>=C2=A0=C2=A0=C2=A0 -&gt; std::array&lt;T=
, detail_::span_count(Cb, Ce)&gt;<br>{...}<br><br>c) return array with elem=
ents initialised to a function applied to each element of the specified seq=
uence:<br>template&lt;typename T, typename F, typename N, N... values&gt;=
=C2=A0=C2=A0=C2=A0 // F is aconstexpr callable with T F(N)<br>constexpr aut=
o eval_discrete_function(detail_::seq&lt;N, values...&gt; &amp;&amp;helper,=
 F &amp;&amp;xf)<br>=C2=A0=C2=A0=C2=A0 -&gt; std::array&lt;T, sizeof...(val=
ues)&gt;<br>{=C2=A0 return {{xf(values)...}}; } // result_of&lt;F(N)::type =
should convert to T<br><br>and<br><br>template&lt;typename F, typename N, N=
.... values&gt;<br>constexpr auto eval_discrete_function(detail_::seq&lt;N, =
values...&gt; &amp;&amp;helper, F &amp;&amp;xf)<br>=C2=A0=C2=A0=C2=A0 -&gt;=
 std::array&lt;typename std::result_of&lt;F(N)&gt;::type, sizeof...(values)=
&gt;<br>{...}<br></div></blockquote><div><br></div><div>This seems much mor=
e reasonable, and has the advantage that the compiler can in many cases cho=
ose to run the initializer at runtime if it&#39;s for a too-large array.</d=
iv><div>=C2=A0</div></div></div></div></blockquote></span><div>Thanks. <br>=
</div><div class=3D"HOEnZb"><div class=3D"h5">

<p></p>

-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--94eb2c0807be414e5a05243510e3--

.