diff options
14 files changed, 71 insertions, 165 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ac5c10a..39fe587 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,29 @@ 2013-01-16 Jonathan Wakely <jwakely.gcc@gmail.com> + PR libstdc++/55043 (again) + * include/bits/alloc_traits.h (allocator_traits::construct): Disable + unless construction would be well-formed. + (__allow_copy_cons, __check_copy_constructible): Define. + * include/bits/unordered_map.h (__check_copy_constructible): Use as + base class so copy constructor will be deleted if appropriate. + (is_copy_constructible): Remove specialization. + * include/bits/unordered_set.h: Likewise. + * include/debug/unordered_map.h: Undo previous commit. Default copy + and move constructors. + * include/debug/unordered_set.h: Likewise. + * include/profile/unordered_map.h: Undo previous commit. + * include/profile/unordered_set.h: Likewise. + * testsuite/23_containers/unordered_map/55043.cc: Fix test. + * testsuite/23_containers/unordered_multimap/55043.cc: Likewise. + * testsuite/23_containers/unordered_multiset/55043.cc: Likewise. + * testsuite/23_containers/unordered_set/55043.cc: Likewise. + * testsuite/23_containers/unordered_map/requirements/53339.cc: XFAIL, + cannot support incomplete types. + * testsuite/23_containers/unordered_multimap/requirements/53339.cc: + Likewise. + +2013-01-16 Jonathan Wakely <jwakely.gcc@gmail.com> + PR libstdc++/55043 * include/std/unordered_map: Include alloc_traits.h * include/std/unordered_set: Likewise. diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h index c6259a1..26c64f2 100644 --- a/libstdc++-v3/include/bits/alloc_traits.h +++ b/libstdc++-v3/include/bits/alloc_traits.h @@ -257,7 +257,8 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap, template<typename _Tp, typename... _Args> static typename - enable_if<!__construct_helper<_Tp, _Args...>::value, void>::type + enable_if<__and_<__not_<__construct_helper<_Tp, _Args...>>, + is_constructible<_Tp, _Args...>>::value, void>::type _S_construct(_Alloc&, _Tp* __p, _Args&&... __args) { ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); } @@ -389,7 +390,8 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap, * arguments @a __args... */ template<typename _Tp, typename... _Args> - static void construct(_Alloc& __a, _Tp* __p, _Args&&... __args) + static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args) + -> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...)) { _S_construct(__a, __p, std::forward<_Args>(__args)...); } /** @@ -526,9 +528,10 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap, _M_select(...); public: - typedef decltype(_M_select<typename _Alloc::value_type>(0)) type; + typedef decltype(_M_select<typename _Alloc::value_type>(0)) type; }; + // true if _Alloc::value_type is CopyInsertable into containers using _Alloc template<typename _Alloc> struct __is_copy_insertable : __is_copy_insertable_impl<_Alloc>::type @@ -540,9 +543,23 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap, : is_copy_constructible<_Tp> { }; - template<typename _Container> - using __has_copy_insertable_val - = __is_copy_insertable<typename _Container::allocator_type>; + // Used to allow copy construction of unordered containers + template<bool> struct __allow_copy_cons { }; + + // Used to delete copy constructor of unordered containers + template<> + struct __allow_copy_cons<false> + { + __allow_copy_cons() = default; + __allow_copy_cons(const __allow_copy_cons&) = delete; + __allow_copy_cons(__allow_copy_cons&&) = default; + __allow_copy_cons& operator=(const __allow_copy_cons&) = default; + __allow_copy_cons& operator=(__allow_copy_cons&&) = default; + }; + + template<typename _Alloc> + using __check_copy_constructible + = __allow_copy_cons<__is_copy_insertable<_Alloc>::value>; _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h index 0235a99..be213e0 100644 --- a/libstdc++-v3/include/bits/unordered_map.h +++ b/libstdc++-v3/include/bits/unordered_map.h @@ -94,7 +94,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>, class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > - class unordered_map + class unordered_map : __check_copy_constructible<_Alloc> { typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable; _Hashtable _M_h; @@ -775,7 +775,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER class _Hash = hash<_Key>, class _Pred = std::equal_to<_Key>, class _Alloc = std::allocator<std::pair<const _Key, _Tp> > > - class unordered_multimap + class unordered_multimap : __check_copy_constructible<_Alloc> { typedef __ummap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc> _Hashtable; _Hashtable _M_h; @@ -1408,26 +1408,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { return !(__x == __y); } _GLIBCXX_END_NAMESPACE_CONTAINER - - template<typename _Key, typename _Tp, typename _Hash, typename _Pred, - typename _Alloc> - struct - is_copy_constructible<_GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, - _Pred, _Alloc>> - : __has_copy_insertable_val<_GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, - _Pred, _Alloc>> - { }; - - template<typename _Key, typename _Tp, typename _Hash, typename _Pred, - typename _Alloc> - struct - is_copy_constructible<_GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, - _Pred, _Alloc>> - : __has_copy_insertable_val<_GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, - _Hash, _Pred, - _Alloc>> - { }; - } // namespace std #endif /* _UNORDERED_MAP_H */ diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h index 2ada63d..50c233d 100644 --- a/libstdc++-v3/include/bits/unordered_set.h +++ b/libstdc++-v3/include/bits/unordered_set.h @@ -90,7 +90,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER class _Hash = hash<_Value>, class _Pred = std::equal_to<_Value>, class _Alloc = std::allocator<_Value> > - class unordered_set + class unordered_set : __check_copy_constructible<_Alloc> { typedef __uset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable; _Hashtable _M_h; @@ -695,7 +695,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER class _Hash = hash<_Value>, class _Pred = std::equal_to<_Value>, class _Alloc = std::allocator<_Value> > - class unordered_multiset + class unordered_multiset : __check_copy_constructible<_Alloc> { typedef __umset_hashtable<_Value, _Hash, _Pred, _Alloc> _Hashtable; _Hashtable _M_h; @@ -1291,23 +1291,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { return !(__x == __y); } _GLIBCXX_END_NAMESPACE_CONTAINER - - template<typename _Key, typename _Hash, typename _Pred, typename _Alloc> - struct is_copy_constructible<_GLIBCXX_STD_C::unordered_set<_Key, _Hash, - _Pred, _Alloc>> - : __has_copy_insertable_val<_GLIBCXX_STD_C::unordered_set<_Key, _Hash, - _Pred, _Alloc>> - { }; - - template<typename _Key, typename _Hash, typename _Pred, typename _Alloc> - struct - is_copy_constructible<_GLIBCXX_STD_C::unordered_multiset<_Key, _Hash, - _Pred, _Alloc>> - : __has_copy_insertable_val<_GLIBCXX_STD_C::unordered_multiset<_Key, _Hash, - _Pred, - _Alloc>> - { }; - } // namespace std #endif /* _UNORDERED_SET_H */ diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map index 115abb5..284450f 100644 --- a/libstdc++-v3/include/debug/unordered_map +++ b/libstdc++-v3/include/debug/unordered_map @@ -96,14 +96,12 @@ namespace __debug __gnu_debug::__base(__last), __n, __hf, __eql, __a) { } - unordered_map(const unordered_map& __x) - : _Base(__x) { } + unordered_map(const unordered_map& __x) = default; unordered_map(const _Base& __x) : _Base(__x) { } - unordered_map(unordered_map&& __x) - : _Base(std::move(__x)) { } + unordered_map(unordered_map&& __x) = default; unordered_map(initializer_list<value_type> __l, size_type __n = 0, @@ -547,14 +545,12 @@ namespace __debug __gnu_debug::__base(__last), __n, __hf, __eql, __a) { } - unordered_multimap(const unordered_multimap& __x) - : _Base(__x) { } + unordered_multimap(const unordered_multimap& __x) = default; unordered_multimap(const _Base& __x) : _Base(__x) { } - unordered_multimap(unordered_multimap&& __x) - : _Base(std::move(__x)) { } + unordered_multimap(unordered_multimap&& __x) = default; unordered_multimap(initializer_list<value_type> __l, size_type __n = 0, @@ -938,30 +934,6 @@ namespace __debug { return !(__x == __y); } } // namespace __debug - -_GLIBCXX_BEGIN_NAMESPACE_VERSION - - template<typename _Key, typename _Tp, typename _Hash, typename _Pred, - typename _Alloc> - struct - is_copy_constructible<__debug::unordered_map<_Key, _Tp, _Hash, _Pred, - _Alloc>> - : is_copy_constructible< _GLIBCXX_STD_C::unordered_map<_Key, _Tp, - _Hash, _Pred, - _Alloc> > - { }; - - template<typename _Key, typename _Tp, typename _Hash, typename _Pred, - typename _Alloc> - struct - is_copy_constructible<__debug::unordered_multimap<_Key, _Tp, _Hash, _Pred, - _Alloc>> - : is_copy_constructible< _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, - _Hash, _Pred, - _Alloc> > - { }; - -_GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set index 895c943..2fe71e4 100644 --- a/libstdc++-v3/include/debug/unordered_set +++ b/libstdc++-v3/include/debug/unordered_set @@ -96,14 +96,12 @@ namespace __debug __gnu_debug::__base(__last), __n, __hf, __eql, __a) { } - unordered_set(const unordered_set& __x) - : _Base(__x) { } + unordered_set(const unordered_set& __x) = default; unordered_set(const _Base& __x) : _Base(__x) { } - unordered_set(unordered_set&& __x) - : _Base(std::move(__x)) { } + unordered_set(unordered_set&& __x) = default; unordered_set(initializer_list<value_type> __l, size_type __n = 0, @@ -542,14 +540,12 @@ namespace __debug __gnu_debug::__base(__last), __n, __hf, __eql, __a) { } - unordered_multiset(const unordered_multiset& __x) - : _Base(__x) { } + unordered_multiset(const unordered_multiset& __x) = default; unordered_multiset(const _Base& __x) : _Base(__x) { } - unordered_multiset(unordered_multiset&& __x) - : _Base(std::move(__x)) { } + unordered_multiset(unordered_multiset&& __x) = default; unordered_multiset(initializer_list<value_type> __l, size_type __n = 0, @@ -920,27 +916,6 @@ namespace __debug { return !(__x == __y); } } // namespace __debug - -_GLIBCXX_BEGIN_NAMESPACE_VERSION - - template<typename _Key, typename _Hash, typename _Pred, typename _Alloc> - struct - is_copy_constructible<__debug::unordered_set<_Key, _Hash, _Pred, _Alloc>> - : is_copy_constructible< _GLIBCXX_STD_C::unordered_set<_Key, - _Hash, _Pred, - _Alloc> > - { }; - - template<typename _Key, typename _Hash, typename _Pred, typename _Alloc> - struct - is_copy_constructible<__debug::unordered_multiset<_Key, _Hash, _Pred, - _Alloc>> - : is_copy_constructible< _GLIBCXX_STD_C::unordered_multiset<_Key, - _Hash, _Pred, - _Alloc> > - { }; - -_GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 diff --git a/libstdc++-v3/include/profile/unordered_map b/libstdc++-v3/include/profile/unordered_map index 5ebcbf6..0fee176 100644 --- a/libstdc++-v3/include/profile/unordered_map +++ b/libstdc++-v3/include/profile/unordered_map @@ -339,25 +339,11 @@ namespace __profile const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } -} // namespace __profile - -_GLIBCXX_BEGIN_NAMESPACE_VERSION - template<typename _Key, typename _Tp, typename _Hash, typename _Pred, - typename _Alloc> - struct - is_copy_constructible<__profile::unordered_map<_Key, _Tp, _Hash, - _Pred, _Alloc>> - : is_copy_constructible< _GLIBCXX_STD_BASE > - { }; -_GLIBCXX_END_NAMESPACE_VERSION - #undef _GLIBCXX_BASE #undef _GLIBCXX_STD_BASE #define _GLIBCXX_BASE unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE -namespace __profile -{ /// Class std::unordered_multimap wrapper with performance instrumentation. template<typename _Key, typename _Tp, typename _Hash = std::hash<_Key>, @@ -623,18 +609,6 @@ namespace __profile { return !(__x == __y); } } // namespace __profile - -_GLIBCXX_BEGIN_NAMESPACE_VERSION - - template<typename _Key, typename _Tp, typename _Hash, typename _Pred, - typename _Alloc> - struct - is_copy_constructible<__profile::unordered_multimap<_Key, _Tp, _Hash, - _Pred, _Alloc>> - : is_copy_constructible< _GLIBCXX_STD_BASE > - { }; - -_GLIBCXX_END_NAMESPACE_VERSION } // namespace std #undef _GLIBCXX_BASE diff --git a/libstdc++-v3/include/profile/unordered_set b/libstdc++-v3/include/profile/unordered_set index ebe1c7d..737b6ec 100644 --- a/libstdc++-v3/include/profile/unordered_set +++ b/libstdc++-v3/include/profile/unordered_set @@ -305,23 +305,11 @@ namespace __profile const unordered_set<_Key, _Hash, _Pred, _Alloc>& __y) { return !(__x == __y); } -} // namespace __profile - -_GLIBCXX_BEGIN_NAMESPACE_VERSION - template<typename _Key, typename _Hash, typename _Pred, typename _Alloc> - struct - is_copy_constructible<__profile::unordered_set<_Key, _Hash, _Pred, _Alloc>> - : is_copy_constructible< _GLIBCXX_STD_BASE > - { }; -_GLIBCXX_END_NAMESPACE_VERSION - #undef _GLIBCXX_BASE #undef _GLIBCXX_STD_BASE #define _GLIBCXX_STD_BASE _GLIBCXX_STD_C::_GLIBCXX_BASE #define _GLIBCXX_BASE unordered_multiset<_Value, _Hash, _Pred, _Alloc> -namespace __profile -{ /** @brief Unordered_multiset wrapper with performance instrumentation. */ template<typename _Value, typename _Hash = std::hash<_Value>, @@ -580,17 +568,6 @@ namespace __profile { return !(__x == __y); } } // namespace __profile - -_GLIBCXX_BEGIN_NAMESPACE_VERSION - - template<typename _Value, typename _Hash, typename _Pred, typename _Alloc> - struct - is_copy_constructible<__profile::unordered_multiset<_Value, _Hash, - _Pred, _Alloc>> - : is_copy_constructible< _GLIBCXX_STD_BASE > - { }; - -_GLIBCXX_END_NAMESPACE_VERSION } // namespace std #undef _GLIBCXX_BASE diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/55043.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/55043.cc index 10d36a0..50e5437 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/55043.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/55043.cc @@ -63,7 +63,7 @@ struct Alloc : std::allocator<T> // verify is_copy_constructible depends on allocator typedef test_type<Alloc<MoveOnly, true>> uim_rval; -static_assert(std::is_copy_constructible<uim_rval>::value, "is not copyable"); +static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable"); typedef test_type<Alloc<MoveOnly, false>> uim_lval; static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable"); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/53339.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/53339.cc index 4df4493..10404ce 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/53339.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/requirements/53339.cc @@ -1,7 +1,9 @@ -// { dg-do compile } +// XFAIL because of PR libstdc++/55043 fix +// { dg-do compile { xfail *-*-* } } +// { dg-excess-errors "" } // { dg-options "-std=gnu++11" } -// Copyright (C) 2012 Free Software Foundation, Inc. +// Copyright (C) 2012-2013 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 diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/55043.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/55043.cc index 9ae912ef6..afeecaa 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/55043.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/55043.cc @@ -63,7 +63,7 @@ struct Alloc : std::allocator<T> // verify is_copy_constructible depends on allocator typedef test_type<Alloc<MoveOnly, true>> uim_rval; -static_assert(std::is_copy_constructible<uim_rval>::value, "is not copyable"); +static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable"); typedef test_type<Alloc<MoveOnly, false>> uim_lval; static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable"); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/53339.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/53339.cc index 5745618..cccd2a8 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/53339.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/requirements/53339.cc @@ -1,7 +1,9 @@ -// { dg-do compile } +// XFAIL because of PR libstdc++/55043 fix +// { dg-do compile { xfail *-*-* } } +// { dg-excess-errors "" } // { dg-options "-std=gnu++11" } -// Copyright (C) 2012 Free Software Foundation, Inc. +// Copyright (C) 2012-2013 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 diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc index ebb8cb8..445e4e4 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/55043.cc @@ -67,7 +67,7 @@ struct Alloc : std::allocator<T> // verify is_copy_constructible depends on allocator typedef test_type<Alloc<MoveOnly, true>> uim_rval; -static_assert(std::is_copy_constructible<uim_rval>::value, "is not copyable"); +static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable"); typedef test_type<Alloc<MoveOnly, false>> uim_lval; static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable"); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc index 3b0b973..e5ba065 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/55043.cc @@ -67,7 +67,7 @@ struct Alloc : std::allocator<T> // verify is_copy_constructible depends on allocator typedef test_type<Alloc<MoveOnly, true>> uim_rval; -static_assert(std::is_copy_constructible<uim_rval>::value, "is not copyable"); +static_assert(!std::is_copy_constructible<uim_rval>::value, "is not copyable"); typedef test_type<Alloc<MoveOnly, false>> uim_lval; static_assert(std::is_copy_constructible<uim_lval>::value, "is copyable"); |