[libcxx] r191692 - SCARY/N2913 iterator support between the multi and non-multi versions of the associative and unordered containers. I beleive lack of support for this was accidentally recently introduced (by me) and this is fixing a regression. This time tests are put in to prevent such a regression in the future.

Howard Hinnant hhinnant at apple.com
Mon Sep 30 12:08:22 PDT 2013


Author: hhinnant
Date: Mon Sep 30 14:08:22 2013
New Revision: 191692

URL: http://llvm.org/viewvc/llvm-project?rev=191692&view=rev
Log:
SCARY/N2913 iterator support between the multi and non-multi versions of the associative and unordered containers.  I beleive lack of support for this was accidentally recently introduced (by me) and this is fixing a regression.  This time tests are put in to prevent such a regression in the future.

Added:
    libcxx/trunk/test/containers/associative/multimap/scary.pass.cpp
    libcxx/trunk/test/containers/associative/multiset/scary.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multimap/scary.pass.cpp
    libcxx/trunk/test/containers/unord/unord.multiset/scary.pass.cpp
Modified:
    libcxx/trunk/include/map
    libcxx/trunk/include/unordered_map

Modified: libcxx/trunk/include/map
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/map?rev=191692&r1=191691&r2=191692&view=diff
==============================================================================
--- libcxx/trunk/include/map (original)
+++ libcxx/trunk/include/map Mon Sep 30 14:08:22 2013
@@ -575,6 +575,75 @@ template <class _Key, class _Tp, class _
     class multimap;
 template <class _TreeIterator> class __map_const_iterator;
 
+#if __cplusplus >= 201103L
+
+template <class _Key, class _Tp>
+union __value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+    typedef pair<key_type, mapped_type>              __nc_value_type;
+
+    value_type __cc;
+    __nc_value_type __nc;
+
+    template <class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(_Args&& ...__args)
+        : __cc(std::forward<_Args>(__args)...) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(const __value_type& __v)
+        : __cc(__v.__cc) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(__value_type& __v)
+        : __cc(__v.__cc) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(__value_type&& __v)
+        : __nc(std::move(__v.__nc)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type& operator=(const __value_type& __v)
+        {__nc = __v.__cc; return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type& operator=(__value_type&& __v)
+        {__nc = std::move(__v.__nc); return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__value_type() {__cc.~value_type();}
+};
+
+#else
+
+template <class _Key, class _Tp>
+struct __value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+
+    value_type __cc;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type() {}
+
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(const _A0& __a0)
+        : __cc(__a0) {}
+
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    __value_type(const _A0& __a0, const _A1& __a1)
+        : __cc(__a0, __a1) {}
+};
+
+#endif
+
 template <class _TreeIterator>
 class _LIBCPP_TYPE_VIS_ONLY __map_iterator
 {
@@ -740,49 +809,7 @@ public:
 
 private:
 
-#if __cplusplus >= 201103L
-    union __value_type
-    {
-        typedef typename map::value_type value_type;
-        typedef typename map::__nc_value_type __nc_value_type;
-        value_type __cc;
-        __nc_value_type __nc;
-
-        template <class ..._Args>
-        __value_type(_Args&& ...__args)
-            : __cc(std::forward<_Args>(__args)...) {}
-
-        __value_type(const __value_type& __v)
-            : __cc(__v.__cc) {}
-
-        __value_type(__value_type&& __v)
-            : __nc(std::move(__v.__nc)) {}
-
-        __value_type& operator=(const __value_type& __v)
-            {__nc = __v.__cc; return *this;}
-
-        __value_type& operator=(__value_type&& __v)
-            {__nc = std::move(__v.__nc); return *this;}
-
-        ~__value_type() {__cc.~value_type();}
-    };
-#else
-    struct __value_type
-    {
-        typedef typename map::value_type value_type;
-        value_type __cc;
-
-        __value_type() {}
-
-        template <class _A0>
-        __value_type(const _A0& __a0)
-            : __cc(__a0) {}
-
-        template <class _A0, class _A1>
-        __value_type(const _A0& __a0, const _A1& __a1)
-            : __cc(__a0, __a1) {}
-    };
-#endif
+    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
     typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
     typedef typename allocator_traits<allocator_type>::template
 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
@@ -1512,49 +1539,8 @@ public:
     };
 
 private:
-#if __cplusplus >= 201103L
-    union __value_type
-    {
-        typedef typename multimap::value_type value_type;
-        typedef typename multimap::__nc_value_type __nc_value_type;
-        value_type __cc;
-        __nc_value_type __nc;
-
-        template <class ..._Args>
-        __value_type(_Args&& ...__args)
-            : __cc(std::forward<_Args>(__args)...) {}
-
-        __value_type(const __value_type& __v)
-            : __cc(std::move(__v.__cc)) {}
-
-        __value_type(__value_type&& __v)
-            : __nc(std::move(__v.__nc)) {}
-
-        __value_type& operator=(const __value_type& __v)
-            {__nc = __v.__cc; return *this;}
 
-        __value_type& operator=(__value_type&& __v)
-            {__nc = std::move(__v.__nc); return *this;}
-
-        ~__value_type() {__cc.~value_type();}
-    };
-#else
-    struct __value_type
-    {
-        typedef typename multimap::value_type value_type;
-        value_type __cc;
-
-        __value_type() {}
-
-        template <class _A0>
-        __value_type(const _A0& __a0)
-            : __cc(__a0) {}
-
-        template <class _A0, class _A1>
-        __value_type(const _A0& __a0, const _A1& __a1)
-            : __cc(__a0, __a1) {}
-    };
-#endif
+    typedef _VSTD::__value_type<key_type, mapped_type>             __value_type;
     typedef __map_value_compare<key_type, __value_type, key_compare> __vc;
     typedef typename allocator_traits<allocator_type>::template
 #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES

Modified: libcxx/trunk/include/unordered_map
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/unordered_map?rev=191692&r1=191691&r2=191692&view=diff
==============================================================================
--- libcxx/trunk/include/unordered_map (original)
+++ libcxx/trunk/include/unordered_map Mon Sep 30 14:08:22 2013
@@ -525,6 +525,71 @@ public:
     }
 };
 
+#if __cplusplus >= 201103L
+
+template <class _Key, class _Tp>
+union __hash_value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+    typedef pair<key_type, mapped_type>              __nc_value_type;
+
+    value_type __cc;
+    __nc_value_type __nc;
+
+    template <class ..._Args>
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(_Args&& ...__args)
+        : __cc(std::forward<_Args>(__args)...) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(const __hash_value_type& __v)
+        : __cc(__v.__cc) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(__hash_value_type&& __v)
+        : __nc(std::move(__v.__nc)) {}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type& operator=(const __hash_value_type& __v)
+        {__nc = __v.__cc; return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type& operator=(__hash_value_type&& __v)
+        {__nc = std::move(__v.__nc); return *this;}
+
+    _LIBCPP_INLINE_VISIBILITY
+    ~__hash_value_type() {__cc.~value_type();}
+};
+
+#else
+
+template <class _Key, class _Tp>
+struct __hash_value_type
+{
+    typedef _Key                                     key_type;
+    typedef _Tp                                      mapped_type;
+    typedef pair<const key_type, mapped_type>        value_type;
+
+    value_type __cc;
+
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type() {}
+
+    template <class _A0>
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(const _A0& __a0)
+        : __cc(__a0) {}
+
+    template <class _A0, class _A1>
+    _LIBCPP_INLINE_VISIBILITY
+    __hash_value_type(const _A0& __a0, const _A1& __a1)
+        : __cc(__a0, __a1) {}
+};
+
+#endif
+
 template <class _HashIterator>
 class _LIBCPP_TYPE_VIS_ONLY __hash_map_iterator
 {
@@ -660,49 +725,7 @@ public:
                   "Invalid allocator::value_type");
 
 private:
-#if __cplusplus >= 201103L
-    union __value_type
-    {
-        typedef typename unordered_map::value_type value_type;
-        typedef typename unordered_map::__nc_value_type __nc_value_type;
-        value_type __cc;
-        __nc_value_type __nc;
-
-        template <class ..._Args>
-        __value_type(_Args&& ...__args)
-            : __cc(std::forward<_Args>(__args)...) {}
-
-        __value_type(const __value_type& __v)
-            : __cc(__v.__cc) {}
-
-        __value_type(__value_type&& __v)
-            : __nc(std::move(__v.__nc)) {}
-
-        __value_type& operator=(const __value_type& __v)
-            {__nc = __v.__cc; return *this;}
-
-        __value_type& operator=(__value_type&& __v)
-            {__nc = std::move(__v.__nc); return *this;}
-
-        ~__value_type() {__cc.~value_type();}
-    };
-#else
-    struct __value_type
-    {
-        typedef typename unordered_map::value_type value_type;
-        value_type __cc;
-
-        __value_type() {}
-
-        template <class _A0>
-        __value_type(const _A0& __a0)
-            : __cc(__a0) {}
-
-        template <class _A0, class _A1>
-        __value_type(const _A0& __a0, const _A1& __a1)
-            : __cc(__a0, __a1) {}
-    };
-#endif
+    typedef __hash_value_type<key_type, mapped_type>                 __value_type;
     typedef __unordered_map_hasher<key_type, __value_type, hasher>   __hasher;
     typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;
     typedef typename allocator_traits<allocator_type>::template
@@ -1439,49 +1462,7 @@ public:
                   "Invalid allocator::value_type");
 
 private:
-#if __cplusplus >= 201103L
-    union __value_type
-    {
-        typedef typename unordered_multimap::value_type value_type;
-        typedef typename unordered_multimap::__nc_value_type __nc_value_type;
-        value_type __cc;
-        __nc_value_type __nc;
-
-        template <class ..._Args>
-        __value_type(_Args&& ...__args)
-            : __cc(std::forward<_Args>(__args)...) {}
-
-        __value_type(const __value_type& __v)
-            : __cc(std::move(__v.__cc)) {}
-
-        __value_type(__value_type&& __v)
-            : __nc(std::move(__v.__nc)) {}
-
-        __value_type& operator=(const __value_type& __v)
-            {__nc = __v.__cc; return *this;}
-
-        __value_type& operator=(__value_type&& __v)
-            {__nc = std::move(__v.__nc); return *this;}
-
-        ~__value_type() {__cc.~value_type();}
-    };
-#else
-    struct __value_type
-    {
-        typedef typename unordered_multimap::value_type value_type;
-        value_type __cc;
-
-        __value_type() {}
-
-        template <class _A0>
-        __value_type(const _A0& __a0)
-            : __cc(__a0) {}
-
-        template <class _A0, class _A1>
-        __value_type(const _A0& __a0, const _A1& __a1)
-            : __cc(__a0, __a1) {}
-    };
-#endif
+    typedef __hash_value_type<key_type, mapped_type>                 __value_type;
     typedef __unordered_map_hasher<key_type, __value_type, hasher>   __hasher;
     typedef __unordered_map_equal<key_type, __value_type, key_equal> __key_equal;
     typedef typename allocator_traits<allocator_type>::template

Added: libcxx/trunk/test/containers/associative/multimap/scary.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/associative/multimap/scary.pass.cpp?rev=191692&view=auto
==============================================================================
--- libcxx/trunk/test/containers/associative/multimap/scary.pass.cpp (added)
+++ libcxx/trunk/test/containers/associative/multimap/scary.pass.cpp Mon Sep 30 14:08:22 2013
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// <map>
+
+// class map class multimap
+
+// Extension:  SCARY/N2913 iterator compatibility between map and multimap
+
+#include <map>
+
+int main()
+{
+    typedef std::map<int, int> M1;
+    typedef std::multimap<int, int> M2;
+    M2::iterator i;
+    M1::iterator j = i;
+}

Added: libcxx/trunk/test/containers/associative/multiset/scary.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/associative/multiset/scary.pass.cpp?rev=191692&view=auto
==============================================================================
--- libcxx/trunk/test/containers/associative/multiset/scary.pass.cpp (added)
+++ libcxx/trunk/test/containers/associative/multiset/scary.pass.cpp Mon Sep 30 14:08:22 2013
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// <set>
+
+// class set class multiset
+
+// Extension:  SCARY/N2913 iterator compatibility between set and multiset
+
+#include <set>
+
+int main()
+{
+    typedef std::set<int> M1;
+    typedef std::multiset<int> M2;
+    M2::iterator i;
+    M1::iterator j = i;
+}

Added: libcxx/trunk/test/containers/unord/unord.multimap/scary.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multimap/scary.pass.cpp?rev=191692&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multimap/scary.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multimap/scary.pass.cpp Mon Sep 30 14:08:22 2013
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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>
+
+// class unordered_map class unordered_multimap
+
+// Extension:  SCARY/N2913 iterator compatibility between unordered_map and unordered_multimap
+
+#include <unordered_map>
+
+int main()
+{
+    typedef std::unordered_map<int, int> M1;
+    typedef std::unordered_multimap<int, int> M2;
+    M2::iterator i;
+    M1::iterator j = i;
+}

Added: libcxx/trunk/test/containers/unord/unord.multiset/scary.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/containers/unord/unord.multiset/scary.pass.cpp?rev=191692&view=auto
==============================================================================
--- libcxx/trunk/test/containers/unord/unord.multiset/scary.pass.cpp (added)
+++ libcxx/trunk/test/containers/unord/unord.multiset/scary.pass.cpp Mon Sep 30 14:08:22 2013
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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>
+
+// class unordered_set class unordered_multiset
+
+// Extension:  SCARY/N2913 iterator compatibility between unordered_set and unordered_multiset
+
+#include <unordered_set>
+
+int main()
+{
+    typedef std::unordered_set<int> M1;
+    typedef std::unordered_multiset<int> M2;
+    M2::iterator i;
+    M1::iterator j = i;
+}





More information about the cfe-commits mailing list