Commit d331c5f1 by Jonathan Wakely Committed by Jonathan Wakely

PR libstdc++/89416 fix __is_move_insertable trait

The common base class for __is_move_insertable and __is_copy_insertable
instantiates both the copy and move tests, when only one is needed. The
unneeded one might cause errors outside the immediate context.

The solution used in this patch is to replace them with alias templates,
which will only be instantiated as needed.

	PR libstdc++/89416
	* include/bits/alloc_traits.h (__is_alloc_insertable_impl): Replace
	class template with class. Replace move and copy member types with
	member alias templates, so they are only instantiated when needed.
	(__is_copy_insertable, __is_move_insertable): Adjust base class.
	* testsuite/23_containers/vector/modifiers/push_back/89130.cc: Enable
	test for C++11/14/17 as well.
	* testsuite/23_containers/vector/modifiers/push_back/89416.cc: New
	test.

From-SVN: r269075
parent f43044a3
2019-02-21 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/89416
* include/bits/alloc_traits.h (__is_alloc_insertable_impl): Replace
class template with class. Replace move and copy member types with
member alias templates, so they are only instantiated when needed.
(__is_copy_insertable, __is_move_insertable): Adjust base class.
* testsuite/23_containers/vector/modifiers/push_back/89130.cc: Enable
test for C++11/14/17 as well.
* testsuite/23_containers/vector/modifiers/push_back/89416.cc: New
test.
2019-02-20 Jakub Jelinek <jakub@redhat.com> 2019-02-20 Jakub Jelinek <jakub@redhat.com>
PR libstdc++/89402 PR libstdc++/89402
......
...@@ -576,33 +576,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -576,33 +576,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__do_alloc_on_swap(__one, __two, __pocs()); __do_alloc_on_swap(__one, __two, __pocs());
} }
template<typename _Alloc> class __is_alloc_insertable_impl
class __is_alloc_insertable_impl {
{ template<typename _Alloc, typename _Up,
using _Traits = allocator_traits<_Alloc>; typename _Tp = __remove_cvref_t<_Up>,
using value_type = typename _Traits::value_type; typename = decltype(allocator_traits<_Alloc>::construct(
std::declval<_Alloc&>(), std::declval<_Tp*>(),
template<typename _Up, typename _Tp = __remove_cvref_t<_Up>, std::declval<_Up>()))>
typename static true_type
= decltype(_Traits::construct(std::declval<_Alloc&>(), _M_select(int);
std::declval<_Tp*>(),
std::declval<_Up>()))> template<typename, typename>
static true_type static false_type
_M_select(int); _M_select(...);
template<typename _Up> protected:
static false_type template<typename _Alloc, typename _Tp = typename _Alloc::value_type>
_M_select(...); using copy = decltype(_M_select<_Alloc, const _Tp&>(0));
public: template<typename _Alloc, typename _Tp = typename _Alloc::value_type>
using copy = decltype(_M_select<const value_type&>(0)); using move = decltype(_M_select<_Alloc, _Tp>(0));
using move = decltype(_M_select<value_type>(0)); };
};
// true if _Alloc::value_type is CopyInsertable into containers using _Alloc // true if _Alloc::value_type is CopyInsertable into containers using _Alloc
template<typename _Alloc> template<typename _Alloc>
struct __is_copy_insertable struct __is_copy_insertable
: __is_alloc_insertable_impl<_Alloc>::copy : __is_alloc_insertable_impl::template copy<_Alloc>
{ }; { };
// std::allocator<_Tp> just requires CopyConstructible // std::allocator<_Tp> just requires CopyConstructible
...@@ -614,7 +613,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -614,7 +613,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// true if _Alloc::value_type is MoveInsertable into containers using _Alloc // true if _Alloc::value_type is MoveInsertable into containers using _Alloc
template<typename _Alloc> template<typename _Alloc>
struct __is_move_insertable struct __is_move_insertable
: __is_alloc_insertable_impl<_Alloc>::move : __is_alloc_insertable_impl::template move<_Alloc>
{ }; { };
// std::allocator<_Tp> just requires MoveConstructible // std::allocator<_Tp> just requires MoveConstructible
......
...@@ -15,8 +15,7 @@ ...@@ -15,8 +15,7 @@
// with this library; see the file COPYING3. If not see // with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++2a" } // { dg-do compile { target c++11 } }
// { dg-do compile { target c++2a } }
#include <vector> #include <vector>
......
// 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
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++11 } }
// PR libstdc++/89416
#include <vector>
template<typename T>
struct Alloc : std::allocator<T>
{
using std::allocator<T>::allocator;
template<typename U>
struct rebind { using other = Alloc<U>; };
};
struct X
{
X(int);
X(X&&);
};
void test01()
{
std::vector<X, Alloc<X>> V;
V.push_back(X(1));
V.emplace_back(1);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment