[libcxx] r260431 - Recommit r260012 - Cleanup node-type handling in the unordered containers.
Eric Fiselier via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 13 00:11:57 PST 2016
> hash_map still looks broken to me.
Uh oh, Sorry :-S. The original breakage was caused by the removal of a
typedef "hash_map" used, but I'm sure I fixed that.
> should not they be prefixed with __gnu_cxx:: ?
No, they are in the correct namespace. The "hash_map" part of the name
means they belong to "<unordered_map>", and the actual type is defined in
that header.
Could you give me more information about the breakage your seeing? The
actual compiler diagnostics if possible? I also committed other sizable
changes to <__hash_table> in r260513 so that may be related.
Let me know if you need this reverted. If possible I would like to hold
off, at least until more is known.
/Eric
On Fri, Feb 12, 2016 at 1:31 PM, Evgenii Stepanov <eugeni.stepanov at gmail.com
> wrote:
> 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 at 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 at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160213/eb902a3b/attachment-0001.html>
More information about the cfe-commits
mailing list