Date: Tue, 1 Mar 2022 19:38:14 +0200
2. @Nikolay, I can't understand how would the following implementation
prevent me from accessing an out-of-bound index, which was the initial
feature wanted to accomplish:
> template<std::size_t IX, typename T>
> auto const &get(T const *a){
> return a[IX];
> }
It doesn't prevent you. But it is the same for std::vector. I am
proposing the code to work in parallel of the fixed array code, not to
replace it.
However for fixed arrays I think we should check -
std::get<IX>(std::array<>) do check the bounds.
On Tue, Mar 1, 2022 at 7:33 PM Paolo Di Giglio <p.digiglio91_at_[hidden]>
wrote:
> Thanks everybody for your precious feedback.
>
> Let me recap what I think I understood and what I surely didn't
> understand:
>
> 1. A specialization of function template std::get for r-value to array
> is still required, and should return a r-value reference to the i-th
> element in the array.
>
> 2. @Nikolay, I can't understand how would the following implementation
> prevent me from accessing an out-of-bound index, which was the initial
> feature wanted to accomplish:
>
> > template<std::size_t IX, typename T>
> > auto const &get(T const *a){
> > return a[IX];
> > }
>
> 3. @Arthur and @DBJ, about the requires vs static_assert implementation,
> I'd stick to the same implementation as std::array. A quick look at the
> MSVC implementation shows they're using static_assert. However, I don't
> know if this is mandated by the standard.
>
> So, at this stage, my proposed implementation of std::get would be the
> following:
>
> template <std::size_t Idx, typename T, std::size_t N>
> constexpr T& get(T (&arr)[N]) noexcept
> {
> static_assert(Idx < N, "Index out of bounds");
> return arr[Idx];
> }
>
> template <std::size_t Idx, typename T, std::size_t N>
> constexpr T&& get(T (&&arr)[N]) noexcept
> {
> static_assert(Idx < N, "Index out of bounds");
>
> using array_t = T(&&)[N];
> return std::forward<array_t>(arr)[Idx];
> }
>
> While four specializations are needed for std::array (i.e. const and
> non-const l- and r-value), I believe only two should suffice here as the
> compiler is able to deduce the const-ness of template parameter T.
>
> Now, about the tuple interface. Thanks @Zhihao for pointing me to you
> earlier work and @Giuseppe for making me aware of P2165. In proposing
> the above std::get specialization, I was actually only trying to let the
> compiler retain as much information as possible about the array to
> perform out-of-bound checks. While I also thought about a specialization
> of std::tuple_size to query the array length, I rejected this idea since
> std::extent already does that.
>
> However, at least in my mind, std::array<T,N> is the C++ version of
> T[N]. So my initial proposal of a new std::get specialization was also
> motivated by the lack symmetry in the standard. By pushing this symmetry
> reasoning further, maybe T[N] should implement the tuple interface,
> since std::array<T,N> does. Is there any drawback in doing so?
>
> Just as a speculation, I'd like to add the following. One step even
> further towards the std::array vs T[N] symmetry would be to specialize
> for std::array the following traits:
>
> * std::rank;
> * std::extent;
> * std::remove_extent;
> * std::remove_all_extents;
>
> I'm not sure if this would introduce breaking changes. Most probably,
> the following specializations for std::array would be breaking changes:
>
> * std::is_array (true);
> * std::is_unbounded_array (false);
> * std::is_bounded_array (true).
>
>
> Il giorno mar 1 mar 2022 alle ore 18:21 Nikolay Mihaylov via Std-Proposals
> <std-proposals_at_[hidden]> ha scritto:
>
>> Sure and since is template parameter, it will still checked for non
>> constexpr version. E.g. kind of.
>>
>> However I still think we can have something similar to pointers too.
>>
>> One more minor point defending pointer version - unless optimized away,
>> this will generate loooots of functions. I love templates, but it will
>> bloat the code.
>>
>> Nick.
>>
>> On Tuesday, March 1, 2022, DBJ via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>> That static_assert will kick in only if the function is called:
>>>
>>> #include <assert.h>
>>> #include <cstdlib>
>>>
>>> template <std::size_t Idx, typename T, std::size_t N>
>>> constexpr T& get(T (&arr)[N]) noexcept {
>>> static_assert(Idx < N, "Index out of bounds");
>>> return arr[Idx];
>>> }
>>>
>>> int main(void) {
>>> constexpr int arr[99] = {1, 2, 3, 4};
>>> static_assert(get<2>(arr) == 3);
>>>
>>> typedef decltype(&get<99>(arr)) wtf;
>>> wtf p = &get<2>(arr); // works
>>> }
>>>
>>> C++20 requires variant is better.
>>>
>>> DBJ
>>>
>>> On Tue, 1 Mar 2022 at 17:39, Arthur O'Dwyer via Std-Proposals <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>>> On Tue, Mar 1, 2022 at 11:34 AM Barry Revzin <barry.revzin_at_[hidden]>
>>>> wrote:
>>>>
>>>>> On Tue, Mar 1, 2022 at 9:59 AM Arthur O'Dwyer via Std-Proposals <
>>>>> std-proposals_at_[hidden]> wrote:
>>>>>
>>>>>> On Tue, Mar 1, 2022 at 10:13 AM Nikolay Mihaylov via Std-Proposals <
>>>>>> std-proposals_at_[hidden]> wrote:
>>>>>>
>>>>>>> Once again, why do we need the size?
>>>>>>> Shall we check the size?
>>>>>>> Via static_assert?
>>>>>>> During runtime?
>>>>>>>
>>>>>>
>>>>>> In the proposed std::get for C arrays, AIUI, the size would be part
>>>>>> of the signature. It would look like this:
>>>>>>
>>>>>> template<size_t X, class T, size_t N> requires (X < N)
>>>>>> constexpr T& get(T (&arr)[N]) noexcept {
>>>>>> return arr[X];
>>>>>> }
>>>>>>
>>>>>
>>>>> No, it wouldn't. Paulo's email contained the correct implementation:
>>>>>
>>>>> template <std::size_t Idx, typename T, std::size_t N>
>>>>> constexpr T& get(T (&arr)[N]) noexcept
>>>>> {
>>>>> static_assert(Idx < N, "Index out of bounds");
>>>>> return arr[Idx];
>>>>> }
>>>>>
>>>>> This would match what std::get does for std::array, std::pair, and
>>>>> std::tuple.
>>>>>
>>>>
>>>> Oh, gross. If it's not going to be SFINAE-friendly, then I don't
>>>> particularly have an opinion what it does.
>>>>
>>>> –Arthur
>>>> --
>>>> Std-Proposals mailing list
>>>> Std-Proposals_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>>
>>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>
prevent me from accessing an out-of-bound index, which was the initial
feature wanted to accomplish:
> template<std::size_t IX, typename T>
> auto const &get(T const *a){
> return a[IX];
> }
It doesn't prevent you. But it is the same for std::vector. I am
proposing the code to work in parallel of the fixed array code, not to
replace it.
However for fixed arrays I think we should check -
std::get<IX>(std::array<>) do check the bounds.
On Tue, Mar 1, 2022 at 7:33 PM Paolo Di Giglio <p.digiglio91_at_[hidden]>
wrote:
> Thanks everybody for your precious feedback.
>
> Let me recap what I think I understood and what I surely didn't
> understand:
>
> 1. A specialization of function template std::get for r-value to array
> is still required, and should return a r-value reference to the i-th
> element in the array.
>
> 2. @Nikolay, I can't understand how would the following implementation
> prevent me from accessing an out-of-bound index, which was the initial
> feature wanted to accomplish:
>
> > template<std::size_t IX, typename T>
> > auto const &get(T const *a){
> > return a[IX];
> > }
>
> 3. @Arthur and @DBJ, about the requires vs static_assert implementation,
> I'd stick to the same implementation as std::array. A quick look at the
> MSVC implementation shows they're using static_assert. However, I don't
> know if this is mandated by the standard.
>
> So, at this stage, my proposed implementation of std::get would be the
> following:
>
> template <std::size_t Idx, typename T, std::size_t N>
> constexpr T& get(T (&arr)[N]) noexcept
> {
> static_assert(Idx < N, "Index out of bounds");
> return arr[Idx];
> }
>
> template <std::size_t Idx, typename T, std::size_t N>
> constexpr T&& get(T (&&arr)[N]) noexcept
> {
> static_assert(Idx < N, "Index out of bounds");
>
> using array_t = T(&&)[N];
> return std::forward<array_t>(arr)[Idx];
> }
>
> While four specializations are needed for std::array (i.e. const and
> non-const l- and r-value), I believe only two should suffice here as the
> compiler is able to deduce the const-ness of template parameter T.
>
> Now, about the tuple interface. Thanks @Zhihao for pointing me to you
> earlier work and @Giuseppe for making me aware of P2165. In proposing
> the above std::get specialization, I was actually only trying to let the
> compiler retain as much information as possible about the array to
> perform out-of-bound checks. While I also thought about a specialization
> of std::tuple_size to query the array length, I rejected this idea since
> std::extent already does that.
>
> However, at least in my mind, std::array<T,N> is the C++ version of
> T[N]. So my initial proposal of a new std::get specialization was also
> motivated by the lack symmetry in the standard. By pushing this symmetry
> reasoning further, maybe T[N] should implement the tuple interface,
> since std::array<T,N> does. Is there any drawback in doing so?
>
> Just as a speculation, I'd like to add the following. One step even
> further towards the std::array vs T[N] symmetry would be to specialize
> for std::array the following traits:
>
> * std::rank;
> * std::extent;
> * std::remove_extent;
> * std::remove_all_extents;
>
> I'm not sure if this would introduce breaking changes. Most probably,
> the following specializations for std::array would be breaking changes:
>
> * std::is_array (true);
> * std::is_unbounded_array (false);
> * std::is_bounded_array (true).
>
>
> Il giorno mar 1 mar 2022 alle ore 18:21 Nikolay Mihaylov via Std-Proposals
> <std-proposals_at_[hidden]> ha scritto:
>
>> Sure and since is template parameter, it will still checked for non
>> constexpr version. E.g. kind of.
>>
>> However I still think we can have something similar to pointers too.
>>
>> One more minor point defending pointer version - unless optimized away,
>> this will generate loooots of functions. I love templates, but it will
>> bloat the code.
>>
>> Nick.
>>
>> On Tuesday, March 1, 2022, DBJ via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>> That static_assert will kick in only if the function is called:
>>>
>>> #include <assert.h>
>>> #include <cstdlib>
>>>
>>> template <std::size_t Idx, typename T, std::size_t N>
>>> constexpr T& get(T (&arr)[N]) noexcept {
>>> static_assert(Idx < N, "Index out of bounds");
>>> return arr[Idx];
>>> }
>>>
>>> int main(void) {
>>> constexpr int arr[99] = {1, 2, 3, 4};
>>> static_assert(get<2>(arr) == 3);
>>>
>>> typedef decltype(&get<99>(arr)) wtf;
>>> wtf p = &get<2>(arr); // works
>>> }
>>>
>>> C++20 requires variant is better.
>>>
>>> DBJ
>>>
>>> On Tue, 1 Mar 2022 at 17:39, Arthur O'Dwyer via Std-Proposals <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>>> On Tue, Mar 1, 2022 at 11:34 AM Barry Revzin <barry.revzin_at_[hidden]>
>>>> wrote:
>>>>
>>>>> On Tue, Mar 1, 2022 at 9:59 AM Arthur O'Dwyer via Std-Proposals <
>>>>> std-proposals_at_[hidden]> wrote:
>>>>>
>>>>>> On Tue, Mar 1, 2022 at 10:13 AM Nikolay Mihaylov via Std-Proposals <
>>>>>> std-proposals_at_[hidden]> wrote:
>>>>>>
>>>>>>> Once again, why do we need the size?
>>>>>>> Shall we check the size?
>>>>>>> Via static_assert?
>>>>>>> During runtime?
>>>>>>>
>>>>>>
>>>>>> In the proposed std::get for C arrays, AIUI, the size would be part
>>>>>> of the signature. It would look like this:
>>>>>>
>>>>>> template<size_t X, class T, size_t N> requires (X < N)
>>>>>> constexpr T& get(T (&arr)[N]) noexcept {
>>>>>> return arr[X];
>>>>>> }
>>>>>>
>>>>>
>>>>> No, it wouldn't. Paulo's email contained the correct implementation:
>>>>>
>>>>> template <std::size_t Idx, typename T, std::size_t N>
>>>>> constexpr T& get(T (&arr)[N]) noexcept
>>>>> {
>>>>> static_assert(Idx < N, "Index out of bounds");
>>>>> return arr[Idx];
>>>>> }
>>>>>
>>>>> This would match what std::get does for std::array, std::pair, and
>>>>> std::tuple.
>>>>>
>>>>
>>>> Oh, gross. If it's not going to be SFINAE-friendly, then I don't
>>>> particularly have an opinion what it does.
>>>>
>>>> –Arthur
>>>> --
>>>> Std-Proposals mailing list
>>>> Std-Proposals_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>>
>>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>
Received on 2022-03-01 17:38:53