From: Jonathan Wakely Date: Thu, 8 Aug 2019 10:18:53 +0000 (+0100) Subject: P0325R4 to_array from LFTS with updates X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cb0de9b60cdc362915e06dfe8a373205d93b232d;p=gcc.git P0325R4 to_array from LFTS with updates As an extension to what the standard requires, this also adds conditional noexcept-specifiers to the std::to_array functions. P0325R4 to_array from LFTS with updates * include/experimental/array (to_array): Qualify call to __to_array. * include/std/array (__cpp_lib_to_array, to_array): Define for C++20. * include/std/version (__cpp_lib_to_array): Likewise. * testsuite/23_containers/array/creation/1.cc: New test. * testsuite/23_containers/array/creation/2.cc: New test. * testsuite/23_containers/array/creation/3_neg.cc: New test. * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc: Use zero for dg-error line number. From-SVN: r274209 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c8b9326bdd1..29418eb9ad9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2019-08-08 Jonathan Wakely + + P0325R4 to_array from LFTS with updates + * include/experimental/array (to_array): Qualify call to __to_array. + * include/std/array (__cpp_lib_to_array, to_array): Define for C++20. + * include/std/version (__cpp_lib_to_array): Likewise. + * testsuite/23_containers/array/creation/1.cc: New test. + * testsuite/23_containers/array/creation/2.cc: New test. + * testsuite/23_containers/array/creation/3_neg.cc: New test. + * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc: + Use zero for dg-error line number. + 2019-08-06 Jonathan Wakely P1651R0 bind_front should not unwrap reference_wrapper diff --git a/libstdc++-v3/include/experimental/array b/libstdc++-v3/include/experimental/array index 5a35fd499d8..0064a0b3b3d 100644 --- a/libstdc++-v3/include/experimental/array +++ b/libstdc++-v3/include/experimental/array @@ -101,7 +101,7 @@ template to_array(_Tp (&__a)[_Nm]) noexcept(is_nothrow_constructible, _Tp&>::value) { - return __to_array(__a, make_index_sequence<_Nm>{}); + return experimental::__to_array(__a, make_index_sequence<_Nm>{}); } // @} group make_array diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array index 31eff9e8e1d..a380f523d44 100644 --- a/libstdc++-v3/include/std/array +++ b/libstdc++-v3/include/std/array @@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * Sets support random access iterators. * * @tparam Tp Type of element. Required to be a complete type. - * @tparam N Number of elements. + * @tparam Nm Number of elements. */ template struct array @@ -343,6 +343,44 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER return std::move(_GLIBCXX_STD_C::get<_Int>(__arr)); } +#if __cplusplus > 201703L +#define __cpp_lib_to_array 201907L + + template + constexpr array, sizeof...(_Idx)> + __to_array(_Tp (&__a)[sizeof...(_Idx)], index_sequence<_Idx...>) + { + if constexpr (_Move) + return {{std::move(__a[_Idx])...}}; + else + return {{__a[_Idx]...}}; + } + + template + constexpr array, _Nm> + to_array(_Tp (&__a)[_Nm]) + noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) + { + static_assert(!is_array_v<_Tp>); + static_assert(is_constructible_v<_Tp, _Tp&>); + if constexpr (is_constructible_v<_Tp, _Tp&>) + return _GLIBCXX_STD_C::__to_array(__a, make_index_sequence<_Nm>{}); + __builtin_unreachable(); // FIXME: see PR c++/91388 + } + + template + constexpr array, _Nm> + to_array(_Tp (&&__a)[_Nm]) + noexcept(is_nothrow_move_constructible_v<_Tp>) + { + static_assert(!is_array_v<_Tp>); + static_assert(is_move_constructible_v<_Tp>); + if constexpr (is_move_constructible_v<_Tp>) + return _GLIBCXX_STD_C::__to_array<1>(__a, make_index_sequence<_Nm>{}); + __builtin_unreachable(); // FIXME: see PR c++/91388 + } +#endif // C++20 + _GLIBCXX_END_NAMESPACE_CONTAINER } // namespace std diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version index 9548725d1b7..5757568d639 100644 --- a/libstdc++-v3/include/std/version +++ b/libstdc++-v3/include/std/version @@ -153,6 +153,7 @@ #define __cpp_lib_atomic_ref 201806L #define __cpp_lib_bind_front 201907L #define __cpp_lib_bounded_array_traits 201902L +#define __cpp_lib_constexpr_algorithms 201711L #if __cpp_impl_destroying_delete # define __cpp_lib_destroying_delete 201806L #endif @@ -164,7 +165,7 @@ #endif #define __cpp_lib_list_remove_return_type 201806L #define __cpp_lib_math_constants 201907L -#define __cpp_lib_constexpr_algorithms 201711L +#define __cpp_lib_to_array 201907L #endif // C++2a #endif // C++17 #endif // C++14 diff --git a/libstdc++-v3/testsuite/23_containers/array/creation/1.cc b/libstdc++-v3/testsuite/23_containers/array/creation/1.cc new file mode 100644 index 00000000000..6279d736353 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/array/creation/1.cc @@ -0,0 +1,57 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include + +#ifndef __cpp_lib_to_array +# error "Feature test macro for to_array is missing" +#elif __cpp_lib_to_array < 201907L +# error "Feature test macro for to_array has wrong value" +#endif + +void test01() +{ + const char x[6]{}; + std::array y = std::to_array(x); + + constexpr char x2[] = "foo"; + constexpr std::array y2 = std::to_array(x2); + static_assert( std::equal(y2.begin(), y2.end(), x2) ); +} + +void +test02() +{ + struct MoveOnly + { + constexpr MoveOnly(int i = 0) : i(i) { } + constexpr MoveOnly(MoveOnly&& m) : i(m.i + 100) { } + int i; + }; + + struct X { + MoveOnly m[3]; + }; + X x; + std::array y = std::to_array(std::move(x).m); + + constexpr std::array y2 = std::to_array(X{{1, 2, 3}}.m); + static_assert( y2[0].i == 101 && y2[1].i == 102 && y2[2].i == 103 ); +} diff --git a/libstdc++-v3/testsuite/23_containers/array/creation/2.cc b/libstdc++-v3/testsuite/23_containers/array/creation/2.cc new file mode 100644 index 00000000000..725f95061b2 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/array/creation/2.cc @@ -0,0 +1,27 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include + +#ifndef __cpp_lib_to_array +# error "Feature test macro for to_array is missing in " +#elif __cpp_lib_to_array < 201907L +# error "Feature test macro for to_array has wrong value in " +#endif diff --git a/libstdc++-v3/testsuite/23_containers/array/creation/3_neg.cc b/libstdc++-v3/testsuite/23_containers/array/creation/3_neg.cc new file mode 100644 index 00000000000..72f389918e0 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/array/creation/3_neg.cc @@ -0,0 +1,56 @@ +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include + +void +test01() +{ + int two_dee[3][4]; + std::to_array(two_dee); // { dg-error "here" } +} + +void +test02() +{ + struct X + { + int two_dee[3][4]; + }; + std::to_array(X{}.two_dee); // { dg-error "here" } +} + +void +test03() +{ + struct MoveOnly + { + MoveOnly() = default; + MoveOnly(MoveOnly&&) = default; + }; + + MoveOnly mo[2]; + std::to_array(mo); // { dg-error "here" } + + const MoveOnly cmo[3]; + std::to_array(std::move(cmo)); // { dg-error "here" } +} + +// { dg-prune-output "static assertion failed" } diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc index 5de55fc3194..393f29de5a7 100644 --- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc @@ -22,4 +22,4 @@ typedef std::tuple_element<1, std::array>::type type; -// { dg-error "static assertion failed" "" { target *-*-* } 372 } +// { dg-error "static assertion failed" "" { target *-*-* } 0 }