Hi EricWF, mclow.lists,

This lets one create types that are aware of their location inside an 
associative container, like this:

class A {
  std::map<int, A>::iterator it;
};

REPOSITORY
  rL LLVM

http://reviews.llvm.org/D7785

Files:
  include/__tree
  include/map
  test/std/containers/associative/map/map.cons/default_recursive.pass.cpp
  
test/std/containers/associative/multimap/multimap.cons/default_recursive.pass.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/__tree
===================================================================
--- include/__tree
+++ include/__tree
@@ -606,8 +606,8 @@
 #endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
 };
 
-template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
-template <class _TreeIterator> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
+template <class _TreeIterator, class _Key, class _Tp> class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
+template <class _TreeIterator, class _Key, class _Tp> class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
 
 template <class _Tp, class _NodePtr, class _DiffType>
 class _LIBCPP_TYPE_VIS_ONLY __tree_iterator
@@ -614,8 +614,6 @@
 {
     typedef _NodePtr                                              __node_pointer;
     typedef typename pointer_traits<__node_pointer>::element_type __node;
-    typedef typename __node::base                                 __node_base;
-    typedef typename __node_base::pointer                         __node_base_pointer;
 
     __node_pointer __ptr_;
 
@@ -644,17 +642,21 @@
         {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
 
     _LIBCPP_INLINE_VISIBILITY
-    __tree_iterator& operator++()
-        {__ptr_ = static_cast<__node_pointer>(__tree_next(static_cast<__node_base_pointer>(__ptr_)));
-         return *this;}
+    __tree_iterator& operator++() {
+      __ptr_ = static_cast<__node_pointer>(
+          __tree_next(static_cast<typename __node::base::pointer>(__ptr_)));
+      return *this;
+    }
     _LIBCPP_INLINE_VISIBILITY
     __tree_iterator operator++(int)
         {__tree_iterator __t(*this); ++(*this); return __t;}
 
     _LIBCPP_INLINE_VISIBILITY
-    __tree_iterator& operator--()
-        {__ptr_ = static_cast<__node_pointer>(__tree_prev(static_cast<__node_base_pointer>(__ptr_)));
-         return *this;}
+    __tree_iterator& operator--() {
+      __ptr_ = static_cast<__node_pointer>(
+          __tree_prev(static_cast<typename __node::base::pointer>(__ptr_)));
+      return *this;
+    }
     _LIBCPP_INLINE_VISIBILITY
     __tree_iterator operator--(int)
         {__tree_iterator __t(*this); --(*this); return __t;}
@@ -671,7 +673,7 @@
     explicit __tree_iterator(__node_pointer __p) _NOEXCEPT : __ptr_(__p) {}
     template <class, class, class> friend class __tree;
     template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator;
-    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __map_iterator;
     template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
     template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
     template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;
@@ -683,14 +685,6 @@
 {
     typedef _ConstNodePtr                                         __node_pointer;
     typedef typename pointer_traits<__node_pointer>::element_type __node;
-    typedef typename __node::base                                 __node_base;
-    typedef typename pointer_traits<__node_pointer>::template
-#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
-            rebind<__node_base>
-#else
-            rebind<__node_base>::other
-#endif
-                                                                  __node_base_pointer;
 
     __node_pointer __ptr_;
 
@@ -735,17 +729,39 @@
         {return pointer_traits<pointer>::pointer_to(__ptr_->__value_);}
 
     _LIBCPP_INLINE_VISIBILITY
-    __tree_const_iterator& operator++()
-        {__ptr_ = static_cast<__node_pointer>(__tree_next(static_cast<__node_base_pointer>(__ptr_)));
-         return *this;}
+    __tree_const_iterator& operator++() {
+      typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+          rebind<typename __node::base>
+#else
+          rebind<typename __node::base>::other
+#endif
+              __node_base_pointer;
+
+      __ptr_ = static_cast<__node_pointer>(
+          __tree_next(static_cast<__node_base_pointer>(__ptr_)));
+      return *this;
+    }
+
     _LIBCPP_INLINE_VISIBILITY
     __tree_const_iterator operator++(int)
         {__tree_const_iterator __t(*this); ++(*this); return __t;}
 
     _LIBCPP_INLINE_VISIBILITY
-    __tree_const_iterator& operator--()
-        {__ptr_ = static_cast<__node_pointer>(__tree_prev(static_cast<__node_base_pointer>(__ptr_)));
-         return *this;}
+    __tree_const_iterator& operator--() {
+      typedef typename pointer_traits<__node_pointer>::template
+#ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES
+          rebind<typename __node::base>
+#else
+          rebind<typename __node::base>::other
+#endif
+              __node_base_pointer;
+
+      __ptr_ = static_cast<__node_pointer>(
+          __tree_prev(static_cast<__node_base_pointer>(__ptr_)));
+      return *this;
+    }
+
     _LIBCPP_INLINE_VISIBILITY
     __tree_const_iterator operator--(int)
         {__tree_const_iterator __t(*this); --(*this); return __t;}
@@ -766,7 +782,7 @@
     template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
     template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY set;
     template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multiset;
-    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
 };
 
 template <class _Tp, class _Compare, class _Allocator>
Index: include/map
===================================================================
--- include/map
+++ include/map
@@ -573,7 +573,7 @@
     class map;
 template <class _Key, class _Tp, class _Compare, class _Allocator>
     class multimap;
-template <class _TreeIterator> class __map_const_iterator;
+template <class _TreeIterator, class _Key, class _Tp> class __map_const_iterator;
 
 #if __cplusplus >= 201103L
 
@@ -644,14 +644,14 @@
 
 #endif
 
-template <class _TreeIterator>
+template <class _TreeIterator, class _Key, class _Tp>
 class _LIBCPP_TYPE_VIS_ONLY __map_iterator
 {
     _TreeIterator __i_;
 
     typedef typename _TreeIterator::__pointer_traits             __pointer_traits;
-    typedef const typename _TreeIterator::value_type::value_type::first_type __key_type;
-    typedef typename _TreeIterator::value_type::value_type::second_type      __mapped_type;
+    typedef const _Key                                           __key_type;
+    typedef _Tp                                                  __mapped_type;
 public:
     typedef bidirectional_iterator_tag                           iterator_category;
     typedef pair<__key_type, __mapped_type>                      value_type;
@@ -706,17 +706,17 @@
 
     template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY map;
     template <class, class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY multimap;
-    template <class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
+    template <class, class, class> friend class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator;
 };
 
-template <class _TreeIterator>
+template <class _TreeIterator, class _Key, class _Tp>
 class _LIBCPP_TYPE_VIS_ONLY __map_const_iterator
 {
     _TreeIterator __i_;
 
     typedef typename _TreeIterator::__pointer_traits             __pointer_traits;
-    typedef const typename _TreeIterator::value_type::value_type::first_type __key_type;
-    typedef typename _TreeIterator::value_type::value_type::second_type      __mapped_type;
+    typedef const _Key                                           __key_type;
+    typedef _Tp                                                  __mapped_type;
 public:
     typedef bidirectional_iterator_tag                           iterator_category;
     typedef pair<__key_type, __mapped_type>                      value_type;
@@ -736,10 +736,9 @@
     _LIBCPP_INLINE_VISIBILITY
     __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}
     _LIBCPP_INLINE_VISIBILITY
-    __map_const_iterator(
-            __map_iterator<typename _TreeIterator::__non_const_iterator> __i)
-                _NOEXCEPT
-                : __i_(__i.__i_) {}
+    __map_const_iterator(__map_iterator<
+        typename _TreeIterator::__non_const_iterator, _Key, _Tp> __i) _NOEXCEPT
+        : __i_(__i.__i_) {}
 
     _LIBCPP_INLINE_VISIBILITY
     reference operator*() const {return __i_->__cc;}
@@ -829,8 +828,8 @@
     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 __map_iterator<typename __base::iterator>      iterator;
-    typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
+    typedef __map_iterator<typename __base::iterator, _Key, _Tp>             iterator;
+    typedef __map_const_iterator<typename __base::const_iterator, _Key, _Tp> const_iterator;
     typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
     typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;
 
@@ -1575,8 +1574,8 @@
     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 __map_iterator<typename __base::iterator>      iterator;
-    typedef __map_const_iterator<typename __base::const_iterator> const_iterator;
+    typedef __map_iterator<typename __base::iterator, _Key, _Tp>      iterator;
+    typedef __map_const_iterator<typename __base::const_iterator, _Key, _Tp> const_iterator;
     typedef _VSTD::reverse_iterator<iterator>               reverse_iterator;
     typedef _VSTD::reverse_iterator<const_iterator>         const_reverse_iterator;
 
Index: test/std/containers/associative/map/map.cons/default_recursive.pass.cpp
===================================================================
--- test/std/containers/associative/map/map.cons/default_recursive.pass.cpp
+++ test/std/containers/associative/map/map.cons/default_recursive.pass.cpp
@@ -20,6 +20,10 @@
 struct X
 {
     std::map<int, X> m;
+    std::map<int, X>::iterator i;
+    std::map<int, X>::const_iterator ci;
+    std::map<int, X>::reverse_iterator ri;
+    std::map<int, X>::const_reverse_iterator cri;
 };
 
 #endif
Index: test/std/containers/associative/multimap/multimap.cons/default_recursive.pass.cpp
===================================================================
--- test/std/containers/associative/multimap/multimap.cons/default_recursive.pass.cpp
+++ test/std/containers/associative/multimap/multimap.cons/default_recursive.pass.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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 multimap
+
+// multimap();
+
+#include <map>
+
+#if !__has_feature(cxx_noexcept)
+
+struct X
+{
+    std::multimap<int, X> m;
+    std::multimap<int, X>::iterator i;
+    std::multimap<int, X>::const_iterator ci;
+    std::multimap<int, X>::reverse_iterator ri;
+    std::multimap<int, X>::const_reverse_iterator cri;
+};
+
+#endif
+
+int main()
+{
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to