Hi, hash_map still looks broken to me. I don't have a simple reproducer, but these declarations in __hash_table:
template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator; template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY __hash_map_const_iterator; should not they be prefixed with __gnu_cxx:: ? Clang says that std::__1::__hash_const_iterator and __gnu_cxx::__hash_map_const_iterator are not friends and __non_const_iterator at ext/hash_map:432 is private. On Wed, Feb 10, 2016 at 12:46 PM, Eric Fiselier via cfe-commits <cfe-commits@lists.llvm.org> wrote: > Author: ericwf > Date: Wed Feb 10 14:46:23 2016 > New Revision: 260431 > > URL: http://llvm.org/viewvc/llvm-project?rev=260431&view=rev > Log: > Recommit r260012 - Cleanup node-type handling in the unordered containers. > > This time I kept <ext/hash_map> working! > > This patch is the first in a series of patches that's meant to better > support unordered_map. unordered_map has a special "value_type" that > differs from pair<const Key, Value>. In order to meet the EmplaceConstructible > and CopyInsertable requirements we need to teach __hash_table about this > special value_type. > > This patch creates a "__hash_node_types" traits class that contains > all of the typedefs needed by the unordered containers and it's iterators. > These typedefs include ones for each node type and node pointer type, > as well as special typedefs for "unordered_map"'s value type. > > As a result of this change all of the unordered containers now all support > incomplete types. > > As a drive-by fix I changed the difference_type in __hash_table to always > be ptrdiff_t. There is a corresponding change to size_type but it cannot > take affect until an ABI break. > > This patch will be followed up shortly with fixes for various unordered_map > bugs and problems. > > Added: > libcxx/trunk/test/libcxx/containers/unord/key_value_traits.pass.cpp > libcxx/trunk/test/std/containers/unord/iterator_difference_type.pass.cpp > libcxx/trunk/test/std/containers/unord/unord.map/incomplete_type.pass.cpp > libcxx/trunk/test/std/containers/unord/unord.multimap/incomplete.pass.cpp > libcxx/trunk/test/std/containers/unord/unord.multiset/incomplete.pass.cpp > libcxx/trunk/test/std/containers/unord/unord.set/incomplete.pass.cpp > Modified: > libcxx/trunk/include/__config > libcxx/trunk/include/__hash_table > libcxx/trunk/include/ext/hash_map > libcxx/trunk/include/unordered_map > > Modified: libcxx/trunk/include/__config > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=260431&r1=260430&r2=260431&view=diff > ============================================================================== > --- libcxx/trunk/include/__config (original) > +++ libcxx/trunk/include/__config Wed Feb 10 14:46:23 2016 > @@ -42,6 +42,7 @@ > // Fix undefined behavior in how std::list stores it's linked nodes. > #define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB > #define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB > +#define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE > #endif > > #define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y > > Modified: libcxx/trunk/include/__hash_table > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__hash_table?rev=260431&r1=260430&r2=260431&view=diff > ============================================================================== > --- libcxx/trunk/include/__hash_table (original) > +++ libcxx/trunk/include/__hash_table Wed Feb 10 14:46:23 2016 > @@ -17,6 +17,7 @@ > #include <iterator> > #include <algorithm> > #include <cmath> > +#include <utility> > > #include <__undef_min_max> > #include <__undef___deallocate> > @@ -49,10 +50,10 @@ struct __hash_node > typename __rebind_pointer<_VoidPtr, __hash_node<_Tp, > _VoidPtr> >::type > > > { > - typedef _Tp value_type; > + typedef _Tp __node_value_type; > > size_t __hash_; > - value_type __value_; > + __node_value_type __value_; > }; > > inline _LIBCPP_INLINE_VISIBILITY > @@ -77,23 +78,126 @@ __next_hash_pow2(size_t __n) > } > > template <class _Tp, class _Hash, class _Equal, class _Alloc> class > __hash_table; > + > +template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_iterator; > template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY > __hash_const_iterator; > +template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY > __hash_local_iterator; > +template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY > __hash_const_local_iterator; > template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY > __hash_map_iterator; > template <class _HashIterator> class _LIBCPP_TYPE_VIS_ONLY > __hash_map_const_iterator; > > +#if __cplusplus >= 201103L > +template <class _Key, class _Tp> > +union __hash_value_type; > +#else > +template <class _Key, class _Tp> > +struct __hash_value_type; > +#endif > + > +template <class _Tp> > +struct __key_value_types { > + static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, ""); > + typedef _Tp key_type; > + typedef _Tp __node_value_type; > + typedef _Tp __container_value_type; > + static const bool __is_map = false; > +}; > + > +template <class _Key, class _Tp> > +struct __key_value_types<__hash_value_type<_Key, _Tp> > { > + typedef _Key key_type; > + typedef _Tp mapped_type; > + typedef __hash_value_type<_Key, _Tp> __node_value_type; > + typedef pair<const _Key, _Tp> > __container_value_type; > + typedef __container_value_type __map_value_type; > + static const bool __is_map = true; > +}; > + > +template <class _Tp, class _AllocPtr, class _KVTypes = > __key_value_types<_Tp>, > + bool = _KVTypes::__is_map> > +struct __map_pointer_types {}; > + > +template <class _Tp, class _AllocPtr, class _KVTypes> > +struct __map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { > + typedef typename _KVTypes::__map_value_type _Mv; > + typedef typename __rebind_pointer<_AllocPtr, _Mv>::type > + > __map_value_type_pointer; > + typedef typename __rebind_pointer<_AllocPtr, const _Mv>::type > + > __const_map_value_type_pointer; > +}; > + > +template <class _NodePtr, class _NodeT = typename > pointer_traits<_NodePtr>::element_type> > +struct __hash_node_types; > + > +template <class _NodePtr, class _Tp, class _VoidPtr> > +struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > > + : public __key_value_types<_Tp>, __map_pointer_types<_Tp, _VoidPtr> > + > +{ > + typedef __key_value_types<_Tp> __base; > + > +public: > + typedef ptrdiff_t difference_type; > + typedef size_t size_type; > + > + typedef typename __rebind_pointer<_NodePtr, void>::type > __void_pointer; > + > + typedef typename pointer_traits<_NodePtr>::element_type __node_type; > + typedef _NodePtr > __node_pointer; > + > + typedef __hash_node_base<__node_pointer> > __node_base_type; > + typedef typename __rebind_pointer<_NodePtr, __node_base_type>::type > + > __node_base_pointer; > + > + typedef _Tp > __node_value_type; > + typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type > + > __node_value_type_pointer; > + typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type > + > __const_node_value_type_pointer; > +private: > + static_assert(!is_const<__node_type>::value, > + "_NodePtr should never be a pointer to const"); > + static_assert((is_same<typename pointer_traits<_VoidPtr>::element_type, > void>::value), > + "_VoidPtr does not point to unqualified void type"); > + static_assert((is_same<typename __rebind_pointer<_VoidPtr, > __node_type>::type, > + _NodePtr>::value), "_VoidPtr does not rebind to > _NodePtr."); > +}; > + > + > + > +template <class _HashIterator> > +struct __hash_node_types_from_iterator; > +template <class _NodePtr> > +struct __hash_node_types_from_iterator<__hash_iterator<_NodePtr> > : > __hash_node_types<_NodePtr> {}; > +template <class _NodePtr> > +struct __hash_node_types_from_iterator<__hash_const_iterator<_NodePtr> > : > __hash_node_types<_NodePtr> {}; > +template <class _NodePtr> > +struct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : > __hash_node_types<_NodePtr> {}; > +template <class _NodePtr> > +struct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > > : __hash_node_types<_NodePtr> {}; > + > + > +template <class _NodeValueTp, class _VoidPtr> > +struct __make_hash_node_types { > + typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp; > + typedef typename __rebind_pointer<_VoidPtr, _NodeTp>::type _NodePtr; > + typedef __hash_node_types<_NodePtr> type; > +}; > + > template <class _NodePtr> > class _LIBCPP_TYPE_VIS_ONLY __hash_iterator > { > - typedef _NodePtr __node_pointer; > + typedef __hash_node_types<_NodePtr> _NodeTypes; > + typedef _NodePtr __node_pointer; > > __node_pointer __node_; > > public: > - typedef forward_iterator_tag iterator_category; > - typedef typename > pointer_traits<__node_pointer>::element_type::value_type value_type; > - typedef typename pointer_traits<__node_pointer>::difference_type > difference_type; > - typedef value_type& reference; > - typedef typename __rebind_pointer<__node_pointer, value_type>::type > pointer; > + typedef forward_iterator_tag iterator_category; > + typedef typename _NodeTypes::__node_value_type value_type; > + typedef typename _NodeTypes::difference_type difference_type; > + typedef value_type& reference; > + typedef typename _NodeTypes::__node_value_type_pointer pointer; > > _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT > #if _LIBCPP_STD_VER > 11 > @@ -202,25 +306,22 @@ private: > template <class, class, class, class, class> friend class > _LIBCPP_TYPE_VIS_ONLY unordered_multimap; > }; > > -template <class _ConstNodePtr> > +template <class _NodePtr> > class _LIBCPP_TYPE_VIS_ONLY __hash_const_iterator > { > - typedef _ConstNodePtr __node_pointer; > - > - __node_pointer __node_; > - > - typedef typename remove_const< > - typename pointer_traits<__node_pointer>::element_type > - >::type __node; > + static_assert(!is_const<typename > pointer_traits<_NodePtr>::element_type>::value, ""); > + typedef __hash_node_types<_NodePtr> _NodeTypes; > + typedef _NodePtr __node_pointer; > + typedef __hash_iterator<_NodePtr> __non_const_iterator; > + __node_pointer __node_; > > public: > - typedef forward_iterator_tag iterator_category; > - typedef typename __node::value_type value_type; > - typedef typename pointer_traits<__node_pointer>::difference_type > difference_type; > - typedef const value_type& reference; > - typedef typename __rebind_pointer<__node_pointer, const > value_type>::type pointer; > - typedef typename __rebind_pointer<__node_pointer, __node>::type > __non_const_node_pointer; > - typedef __hash_iterator<__non_const_node_pointer> __non_const_iterator; > + typedef forward_iterator_tag > iterator_category; > + typedef typename _NodeTypes::__node_value_type value_type; > + typedef typename _NodeTypes::difference_type > difference_type; > + typedef const value_type& reference; > + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; > + > > _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT > #if _LIBCPP_STD_VER > 11 > @@ -336,24 +437,22 @@ private: > template <class, class, class, class, class> friend class > _LIBCPP_TYPE_VIS_ONLY unordered_multimap; > }; > > -template <class _ConstNodePtr> class _LIBCPP_TYPE_VIS_ONLY > __hash_const_local_iterator; > - > template <class _NodePtr> > class _LIBCPP_TYPE_VIS_ONLY __hash_local_iterator > { > - typedef _NodePtr __node_pointer; > + typedef __hash_node_types<_NodePtr> _NodeTypes; > + typedef _NodePtr __node_pointer; > > __node_pointer __node_; > size_t __bucket_; > size_t __bucket_count_; > > - typedef pointer_traits<__node_pointer> __pointer_traits; > public: > typedef forward_iterator_tag > iterator_category; > - typedef typename __pointer_traits::element_type::value_type value_type; > - typedef typename __pointer_traits::difference_type > difference_type; > + typedef typename _NodeTypes::__node_value_type value_type; > + typedef typename _NodeTypes::difference_type > difference_type; > typedef value_type& reference; > - typedef typename __rebind_pointer<__node_pointer, value_type>::type > pointer; > + typedef typename _NodeTypes::__node_value_type_pointer pointer; > > _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT > { > @@ -476,7 +575,8 @@ private: > template <class _ConstNodePtr> > class _LIBCPP_TYPE_VIS_ONLY __hash_const_local_iterator > { > - typedef _ConstNodePtr __node_pointer; > + typedef __hash_node_types<_ConstNodePtr> _NodeTypes; > + typedef _ConstNodePtr __node_pointer; > > __node_pointer __node_; > size_t __bucket_; > @@ -491,14 +591,11 @@ class _LIBCPP_TYPE_VIS_ONLY __hash_const > typedef __hash_local_iterator<__non_const_node_pointer> > __non_const_iterator; > public: > - typedef forward_iterator_tag iterator_category; > - typedef typename remove_const< > - typename __pointer_traits::element_type::value_type > - >::type value_type; > - typedef typename __pointer_traits::difference_type difference_type; > - typedef const value_type& reference; > - typedef typename __rebind_pointer<__node_pointer, const value_type>::type > - pointer; > + typedef forward_iterator_tag > iterator_category; > + typedef typename _NodeTypes::__node_value_type value_type; > + typedef typename _NodeTypes::difference_type > difference_type; > + typedef const value_type& reference; > + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; > > > _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT > @@ -686,7 +783,7 @@ class __hash_node_destructor > { > typedef _Alloc allocator_type; > typedef allocator_traits<allocator_type> __alloc_traits; > - typedef typename __alloc_traits::value_type::value_type value_type; > + > public: > typedef typename __alloc_traits::pointer pointer; > private: > @@ -728,23 +825,42 @@ public: > > private: > typedef allocator_traits<allocator_type> __alloc_traits; > + typedef typename > + __make_hash_node_types<value_type, typename > __alloc_traits::void_pointer>::type > + > _NodeTypes; > public: > typedef value_type& reference; > typedef const value_type& const_reference; > typedef typename __alloc_traits::pointer pointer; > typedef typename __alloc_traits::const_pointer const_pointer; > +#ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE > typedef typename __alloc_traits::size_type size_type; > - typedef typename __alloc_traits::difference_type difference_type; > +#else > + typedef typename _NodeTypes::size_type size_type; > +#endif > + typedef typename _NodeTypes::difference_type difference_type; > public: > // Create __node > - typedef __hash_node<value_type, typename __alloc_traits::void_pointer> > __node; > + > + typedef typename _NodeTypes::__node_type __node; > typedef typename __rebind_alloc_helper<__alloc_traits, __node>::type > __node_allocator; > typedef allocator_traits<__node_allocator> __node_traits; > - typedef typename __node_traits::pointer __node_pointer; > - typedef typename __node_traits::pointer __node_const_pointer; > - typedef __hash_node_base<__node_pointer> __first_node; > - typedef typename __rebind_pointer<__node_pointer, __first_node>::type > - __node_base_pointer; > + typedef typename _NodeTypes::__node_pointer __node_pointer; > + typedef typename _NodeTypes::__node_pointer __node_const_pointer; > + typedef typename _NodeTypes::__node_base_type __first_node; > + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; > + > +private: > + // check for sane allocator pointer rebinding semantics. Rebinding the > + // allocator for a new pointer type should be exactly the same as > rebinding > + // the pointer using 'pointer_traits'. > + static_assert((is_same<__node_pointer, typename > __node_traits::pointer>::value), > + "Allocator does not rebind pointers in a sane manner."); > + typedef typename __rebind_alloc_helper<__node_traits, __first_node>::type > + __node_base_allocator; > + typedef allocator_traits<__node_base_allocator> __node_base_traits; > + static_assert((is_same<__node_base_pointer, typename > __node_base_traits::pointer>::value), > + "Allocator does not rebind pointers in a sane manner."); > > private: > > @@ -755,10 +871,10 @@ private: > typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; > > // --- Member data begin --- > - __bucket_list __bucket_list_; > - __compressed_pair<__first_node, __node_allocator> __p1_; > - __compressed_pair<size_type, hasher> __p2_; > - __compressed_pair<float, key_equal> __p3_; > + __bucket_list __bucket_list_; > + __compressed_pair<__first_node, __node_allocator> __p1_; > + __compressed_pair<size_type, hasher> __p2_; > + __compressed_pair<float, key_equal> __p3_; > // --- Member data end --- > > _LIBCPP_INLINE_VISIBILITY > > Modified: libcxx/trunk/include/ext/hash_map > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/ext/hash_map?rev=260431&r1=260430&r2=260431&view=diff > ============================================================================== > --- libcxx/trunk/include/ext/hash_map (original) > +++ libcxx/trunk/include/ext/hash_map Wed Feb 10 14:46:23 2016 > @@ -309,7 +309,7 @@ class __hash_map_node_destructor > { > typedef _Alloc allocator_type; > typedef allocator_traits<allocator_type> __alloc_traits; > - typedef typename __alloc_traits::value_type::value_type value_type; > + typedef typename __alloc_traits::value_type::__node_value_type > value_type; > public: > typedef typename __alloc_traits::pointer pointer; > private: > > Modified: libcxx/trunk/include/unordered_map > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/unordered_map?rev=260431&r1=260430&r2=260431&view=diff > ============================================================================== > --- libcxx/trunk/include/unordered_map (original) > +++ libcxx/trunk/include/unordered_map Wed Feb 10 14:46:23 2016 > @@ -384,6 +384,7 @@ template <class _Key, class _Cp, class _ > class __unordered_map_hasher > : private _Hash > { > + typedef typename __key_value_types<_Cp>::__map_value_type _PairT; > public: > _LIBCPP_INLINE_VISIBILITY > __unordered_map_hasher() > @@ -414,6 +415,7 @@ class __unordered_map_hasher<_Key, _Cp, > { > _Hash __hash_; > > + typedef typename __key_value_types<_Cp>::__map_value_type _PairT; > public: > _LIBCPP_INLINE_VISIBILITY > __unordered_map_hasher() > @@ -455,6 +457,7 @@ template <class _Key, class _Cp, class _ > class __unordered_map_equal > : private _Pred > { > + typedef typename __key_value_types<_Cp>::__map_value_type _PairT; > public: > _LIBCPP_INLINE_VISIBILITY > __unordered_map_equal() > @@ -488,6 +491,7 @@ class __unordered_map_equal<_Key, _Cp, _ > { > _Pred __pred_; > > + typedef typename __key_value_types<_Cp>::__map_value_type _PairT; > public: > _LIBCPP_INLINE_VISIBILITY > __unordered_map_equal() > @@ -508,6 +512,9 @@ public: > _LIBCPP_INLINE_VISIBILITY > bool operator()(const _Key& __x, const _Cp& __y) const > {return __pred_(__x, __y.__cc.first);} > + _LIBCPP_INLINE_VISIBILITY > + bool operator()(const _Key& __x, const _PairT& __y) const > + {return __pred_(__x, __y.first);} > void swap(__unordered_map_equal&__y) > _NOEXCEPT_(__is_nothrow_swappable<_Pred>::value) > { > @@ -531,12 +538,11 @@ class __hash_map_node_destructor > { > typedef _Alloc allocator_type; > typedef allocator_traits<allocator_type> __alloc_traits; > - typedef typename __alloc_traits::value_type::value_type value_type; > + > public: > - typedef typename __alloc_traits::pointer pointer; > + > + typedef typename __alloc_traits::pointer pointer; > private: > - typedef typename value_type::value_type::first_type first_type; > - typedef typename value_type::value_type::second_type second_type; > > allocator_type& __na_; > > @@ -656,15 +662,14 @@ class _LIBCPP_TYPE_VIS_ONLY __hash_map_i > { > _HashIterator __i_; > > - typedef const typename _HashIterator::value_type::value_type::first_type > key_type; > - typedef typename _HashIterator::value_type::value_type::second_type > mapped_type; > + typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; > + > public: > typedef forward_iterator_tag > iterator_category; > - typedef pair<key_type, mapped_type> value_type; > - typedef typename _HashIterator::difference_type > difference_type; > + typedef typename _NodeTypes::__map_value_type value_type; > + typedef typename _NodeTypes::difference_type > difference_type; > typedef value_type& reference; > - typedef typename __rebind_pointer<typename _HashIterator::pointer, > value_type>::type > - pointer; > + typedef typename _NodeTypes::__map_value_type_pointer pointer; > > _LIBCPP_INLINE_VISIBILITY > __hash_map_iterator() _NOEXCEPT {} > @@ -706,15 +711,14 @@ class _LIBCPP_TYPE_VIS_ONLY __hash_map_c > { > _HashIterator __i_; > > - typedef const typename _HashIterator::value_type::value_type::first_type > key_type; > - typedef typename _HashIterator::value_type::value_type::second_type > mapped_type; > + typedef __hash_node_types_from_iterator<_HashIterator> _NodeTypes; > + > public: > typedef forward_iterator_tag > iterator_category; > - typedef pair<key_type, mapped_type> value_type; > - typedef typename _HashIterator::difference_type > difference_type; > + typedef typename _NodeTypes::__map_value_type value_type; > + typedef typename _NodeTypes::difference_type > difference_type; > typedef const value_type& reference; > - typedef typename __rebind_pointer<typename _HashIterator::pointer, const > value_type>::type > - pointer; > + typedef typename _NodeTypes::__const_map_value_type_pointer pointer; > > _LIBCPP_INLINE_VISIBILITY > __hash_map_const_iterator() _NOEXCEPT {} > @@ -796,8 +800,8 @@ private: > public: > typedef typename __alloc_traits::pointer pointer; > typedef typename __alloc_traits::const_pointer const_pointer; > - typedef typename __alloc_traits::size_type size_type; > - typedef typename __alloc_traits::difference_type difference_type; > + typedef typename __table::size_type size_type; > + typedef typename __table::difference_type difference_type; > > typedef __hash_map_iterator<typename __table::iterator> iterator; > typedef __hash_map_const_iterator<typename __table::const_iterator> > const_iterator; > @@ -1641,11 +1645,14 @@ private: > typedef __hash_map_node_destructor<__node_allocator> _Dp; > typedef unique_ptr<__node, _Dp> __node_holder; > typedef allocator_traits<allocator_type> __alloc_traits; > + static_assert((is_same<typename __node_traits::size_type, > + typename __alloc_traits::size_type>::value), > + "Allocator uses different size_type for different types"); > public: > typedef typename __alloc_traits::pointer pointer; > typedef typename __alloc_traits::const_pointer const_pointer; > - typedef typename __alloc_traits::size_type size_type; > - typedef typename __alloc_traits::difference_type difference_type; > + typedef typename __table::size_type size_type; > + typedef typename __table::difference_type difference_type; > > typedef __hash_map_iterator<typename __table::iterator> iterator; > typedef __hash_map_const_iterator<typename __table::const_iterator> > const_iterator; > > Added: libcxx/trunk/test/libcxx/containers/unord/key_value_traits.pass.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/containers/unord/key_value_traits.pass.cpp?rev=260431&view=auto > ============================================================================== > --- libcxx/trunk/test/libcxx/containers/unord/key_value_traits.pass.cpp > (added) > +++ libcxx/trunk/test/libcxx/containers/unord/key_value_traits.pass.cpp Wed > Feb 10 14:46:23 2016 > @@ -0,0 +1,59 @@ > +//===----------------------------------------------------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is dual licensed under the MIT and the University of Illinois > Open > +// Source Licenses. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#include <__hash_table> > +#include <unordered_map> > +#include <unordered_set> > +#include <type_traits> > + > +#include "test_macros.h" > +#include "min_allocator.h" > + > +void testKeyValueTrait() { > + { > + typedef int Tp; > + typedef std::__key_value_types<Tp> Traits; > + static_assert((std::is_same<Traits::key_type, int>::value), ""); > + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); > + static_assert((std::is_same<Traits::__container_value_type, Tp>::value), > ""); > + static_assert(Traits::__is_map == false, ""); > + } > + { > + typedef std::pair<int, int> Tp; > + typedef std::__key_value_types<Tp> Traits; > + static_assert((std::is_same<Traits::key_type, Tp>::value), ""); > + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); > + static_assert((std::is_same<Traits::__container_value_type, Tp>::value), > ""); > + static_assert(Traits::__is_map == false, ""); > + } > + { > + typedef std::pair<const int, int> Tp; > + typedef std::__key_value_types<Tp> Traits; > + static_assert((std::is_same<Traits::key_type, Tp>::value), ""); > + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); > + static_assert((std::is_same<Traits::__container_value_type, Tp>::value), > ""); > + static_assert(Traits::__is_map == false, ""); > + } > + { > + typedef std::__hash_value_type<int, int> Tp; > + typedef std::__key_value_types<Tp> Traits; > + static_assert((std::is_same<Traits::key_type, int>::value), ""); > + static_assert((std::is_same<Traits::mapped_type, int>::value), ""); > + static_assert((std::is_same<Traits::__node_value_type, Tp>::value), ""); > + static_assert((std::is_same<Traits::__container_value_type, > + std::pair<const int, int> >::value), ""); > + static_assert((std::is_same<Traits::__map_value_type, > + std::pair<const int, int> >::value), ""); > + static_assert(Traits::__is_map == true, ""); > + } > +} > + > +int main() { > + testKeyValueTrait(); > +} > > Added: > libcxx/trunk/test/std/containers/unord/iterator_difference_type.pass.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/unord/iterator_difference_type.pass.cpp?rev=260431&view=auto > ============================================================================== > --- libcxx/trunk/test/std/containers/unord/iterator_difference_type.pass.cpp > (added) > +++ libcxx/trunk/test/std/containers/unord/iterator_difference_type.pass.cpp > Wed Feb 10 14:46:23 2016 > @@ -0,0 +1,154 @@ > +//===----------------------------------------------------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is dual licensed under the MIT and the University of Illinois > Open > +// Source Licenses. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#include <unordered_map> > +#include <unordered_set> > +#include <type_traits> > + > +#include "test_macros.h" > +#include "min_allocator.h" > +#include "test_allocator.h" > + > + > +template <class Map, class ValueTp, class PtrT, class CPtrT> > +void testUnorderedMap() { > + typedef typename Map::difference_type Diff; > + { > + typedef typename Map::iterator It; > + static_assert((std::is_same<typename It::value_type, ValueTp>::value), > ""); > + static_assert((std::is_same<typename It::reference, ValueTp&>::value), > ""); > + static_assert((std::is_same<typename It::pointer, PtrT>::value), ""); > + static_assert((std::is_same<typename It::difference_type, Diff>::value), > ""); > + } > + { > + typedef typename Map::const_iterator It; > + static_assert((std::is_same<typename It::value_type, ValueTp>::value), > ""); > + static_assert((std::is_same<typename It::reference, ValueTp > const&>::value), ""); > + static_assert((std::is_same<typename It::pointer, CPtrT>::value), ""); > + static_assert((std::is_same<typename It::difference_type, Diff>::value), > ""); > + } > + { > + typedef typename Map::local_iterator It; > + static_assert((std::is_same<typename It::value_type, ValueTp>::value), > ""); > + static_assert((std::is_same<typename It::reference, ValueTp&>::value), > ""); > + static_assert((std::is_same<typename It::pointer, PtrT>::value), ""); > + static_assert((std::is_same<typename It::difference_type, Diff>::value), > ""); > + } > + { > + typedef typename Map::const_local_iterator It; > + static_assert((std::is_same<typename It::value_type, ValueTp>::value), > ""); > + static_assert((std::is_same<typename It::reference, ValueTp > const&>::value), ""); > + static_assert((std::is_same<typename It::pointer, CPtrT>::value), ""); > + static_assert((std::is_same<typename It::difference_type, Diff>::value), > ""); > + } > +} > + > + > +template <class Set, class ValueTp, class CPtrT> > +void testUnorderedSet() { > + static_assert((std::is_same<typename Set::iterator, > + typename Set::const_iterator>::value), ""); > + static_assert((std::is_same<typename Set::local_iterator, > + typename Set::const_local_iterator>::value), > ""); > + typedef typename Set::difference_type Diff; > + { > + typedef typename Set::iterator It; > + static_assert((std::is_same<typename It::value_type, ValueTp>::value), > ""); > + static_assert((std::is_same<typename It::reference, ValueTp > const&>::value), ""); > + static_assert((std::is_same<typename It::pointer, CPtrT>::value), ""); > + static_assert((std::is_same<typename It::difference_type, Diff>::value), > ""); > + > + } > + { > + typedef typename Set::local_iterator It; > + static_assert((std::is_same<typename It::value_type, ValueTp>::value), > ""); > + static_assert((std::is_same<typename It::reference, ValueTp > const&>::value), ""); > + static_assert((std::is_same<typename It::pointer, CPtrT>::value), ""); > + static_assert((std::is_same<typename It::difference_type, Diff>::value), > ""); > + } > +} > + > +int main() { > + { > + typedef std::unordered_map<int, int> Map; > + typedef std::pair<const int, int> ValueTp; > + testUnorderedMap<Map, ValueTp, ValueTp*, ValueTp const*>(); > + } > + { > + typedef std::pair<const int, int> ValueTp; > + typedef test_allocator<ValueTp> Alloc; > + typedef std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, > Alloc> Map; > + testUnorderedMap<Map, ValueTp, ValueTp*, ValueTp const*>(); > + } > +#if TEST_STD_VER >= 11 > + { > + typedef std::pair<const int, int> ValueTp; > + typedef min_allocator<ValueTp> Alloc; > + typedef std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, > Alloc> Map; > + testUnorderedMap<Map, ValueTp, min_pointer<ValueTp>, min_pointer<const > ValueTp>>(); > + } > +#endif > + { > + typedef std::unordered_multimap<int, int> Map; > + typedef std::pair<const int, int> ValueTp; > + testUnorderedMap<Map, ValueTp, ValueTp*, ValueTp const*>(); > + } > + { > + typedef std::pair<const int, int> ValueTp; > + typedef test_allocator<ValueTp> Alloc; > + typedef std::unordered_multimap<int, int, std::hash<int>, > std::equal_to<int>, Alloc> Map; > + testUnorderedMap<Map, ValueTp, ValueTp*, ValueTp const*>(); > + } > +#if TEST_STD_VER >= 11 > + { > + typedef std::pair<const int, int> ValueTp; > + typedef min_allocator<ValueTp> Alloc; > + typedef std::unordered_multimap<int, int, std::hash<int>, > std::equal_to<int>, Alloc> Map; > + testUnorderedMap<Map, ValueTp, min_pointer<ValueTp>, min_pointer<const > ValueTp>>(); > + } > +#endif > + { > + typedef int ValueTp; > + typedef std::unordered_set<ValueTp> Set; > + testUnorderedSet<Set, ValueTp, ValueTp const*>(); > + } > + { > + typedef int ValueTp; > + typedef test_allocator<ValueTp> Alloc; > + typedef std::unordered_set<ValueTp, std::hash<ValueTp>, > std::equal_to<ValueTp>, Alloc> Set; > + testUnorderedSet<Set, ValueTp, ValueTp const*>(); > + } > +#if TEST_STD_VER >= 11 > + { > + typedef int ValueTp; > + typedef min_allocator<ValueTp> Alloc; > + typedef std::unordered_set<ValueTp, std::hash<ValueTp>, > std::equal_to<ValueTp>, Alloc> Set; > + testUnorderedSet<Set, ValueTp, min_pointer<const ValueTp>>(); > + } > +#endif > + { > + typedef int ValueTp; > + typedef std::unordered_multiset<ValueTp> Set; > + testUnorderedSet<Set, ValueTp, ValueTp const*>(); > + } > + { > + typedef int ValueTp; > + typedef test_allocator<ValueTp> Alloc; > + typedef std::unordered_multiset<ValueTp, std::hash<ValueTp>, > std::equal_to<ValueTp>, Alloc> Set; > + testUnorderedSet<Set, ValueTp, ValueTp const*>(); > + } > +#if TEST_STD_VER >= 11 > + { > + typedef int ValueTp; > + typedef min_allocator<ValueTp> Alloc; > + typedef std::unordered_multiset<ValueTp, std::hash<ValueTp>, > std::equal_to<ValueTp>, Alloc> Set; > + testUnorderedSet<Set, ValueTp, min_pointer<const ValueTp>>(); > + } > +#endif > +} > > Added: > libcxx/trunk/test/std/containers/unord/unord.map/incomplete_type.pass.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/unord/unord.map/incomplete_type.pass.cpp?rev=260431&view=auto > ============================================================================== > --- libcxx/trunk/test/std/containers/unord/unord.map/incomplete_type.pass.cpp > (added) > +++ libcxx/trunk/test/std/containers/unord/unord.map/incomplete_type.pass.cpp > Wed Feb 10 14:46:23 2016 > @@ -0,0 +1,37 @@ > + > +//===----------------------------------------------------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is dual licensed under the MIT and the University of Illinois > Open > +// Source Licenses. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +// <unordered_map> > + > +// Check that std::unordered_map and it's iterators can be instantiated with > an incomplete > +// type. > + > +#include <unordered_map> > + > +template <class Tp> > +struct MyHash { > + MyHash() {} > + std::size_t operator()(Tp const&) const {return 42;} > +}; > + > +struct A { > + typedef std::unordered_map<A, A, MyHash<A> > Map; > + Map m; > + Map::iterator it; > + Map::const_iterator cit; > + Map::local_iterator lit; > + Map::const_local_iterator clit; > +}; > + > +inline bool operator==(A const& L, A const& R) { return &L == &R; } > + > +int main() { > + A a; > +} > > Added: > libcxx/trunk/test/std/containers/unord/unord.multimap/incomplete.pass.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/unord/unord.multimap/incomplete.pass.cpp?rev=260431&view=auto > ============================================================================== > --- libcxx/trunk/test/std/containers/unord/unord.multimap/incomplete.pass.cpp > (added) > +++ libcxx/trunk/test/std/containers/unord/unord.multimap/incomplete.pass.cpp > Wed Feb 10 14:46:23 2016 > @@ -0,0 +1,37 @@ > + > +//===----------------------------------------------------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is dual licensed under the MIT and the University of Illinois > Open > +// Source Licenses. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +// <unordered_map> > + > +// Check that std::unordered_multimap and it's iterators can be instantiated > with an incomplete > +// type. > + > +#include <unordered_map> > + > +template <class Tp> > +struct MyHash { > + MyHash() {} > + std::size_t operator()(Tp const&) const {return 42;} > +}; > + > +struct A { > + typedef std::unordered_multimap<A, A, MyHash<A> > Map; > + Map m; > + Map::iterator it; > + Map::const_iterator cit; > + Map::local_iterator lit; > + Map::const_local_iterator clit; > +}; > + > +inline bool operator==(A const& L, A const& R) { return &L == &R; } > + > +int main() { > + A a; > +} > > Added: > libcxx/trunk/test/std/containers/unord/unord.multiset/incomplete.pass.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/unord/unord.multiset/incomplete.pass.cpp?rev=260431&view=auto > ============================================================================== > --- libcxx/trunk/test/std/containers/unord/unord.multiset/incomplete.pass.cpp > (added) > +++ libcxx/trunk/test/std/containers/unord/unord.multiset/incomplete.pass.cpp > Wed Feb 10 14:46:23 2016 > @@ -0,0 +1,38 @@ > + > + > +//===----------------------------------------------------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is dual licensed under the MIT and the University of Illinois > Open > +// Source Licenses. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +// <unordered_set> > + > +// Check that std::unordered_multiset and it's iterators can be instantiated > with an incomplete > +// type. > + > +#include <unordered_set> > + > +template <class Tp> > +struct MyHash { > + MyHash() {} > + std::size_t operator()(Tp const&) const {return 42;} > +}; > + > +struct A { > + typedef std::unordered_multiset<A, MyHash<A> > Map; > + Map m; > + Map::iterator it; > + Map::const_iterator cit; > + Map::local_iterator lit; > + Map::const_local_iterator clit; > +}; > + > +inline bool operator==(A const& L, A const& R) { return &L == &R; } > + > +int main() { > + A a; > +} > > Added: libcxx/trunk/test/std/containers/unord/unord.set/incomplete.pass.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/unord/unord.set/incomplete.pass.cpp?rev=260431&view=auto > ============================================================================== > --- libcxx/trunk/test/std/containers/unord/unord.set/incomplete.pass.cpp > (added) > +++ libcxx/trunk/test/std/containers/unord/unord.set/incomplete.pass.cpp Wed > Feb 10 14:46:23 2016 > @@ -0,0 +1,38 @@ > + > + > +//===----------------------------------------------------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is dual licensed under the MIT and the University of Illinois > Open > +// Source Licenses. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +// <unordered_set> > + > +// Check that std::unordered_set and it's iterators can be instantiated with > an incomplete > +// type. > + > +#include <unordered_set> > + > +template <class Tp> > +struct MyHash { > + MyHash() {} > + std::size_t operator()(Tp const&) const {return 42;} > +}; > + > +struct A { > + typedef std::unordered_set<A, MyHash<A> > Map; > + Map m; > + Map::iterator it; > + Map::const_iterator cit; > + Map::local_iterator lit; > + Map::const_local_iterator clit; > +}; > + > +inline bool operator==(A const& L, A const& R) { return &L == &R; } > + > +int main() { > + A a; > +} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits