From b3be398c67ddb8d2f98480cc5540607a68b1ac88 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Tue, 3 Mar 2015 20:10:01 +0000 Subject: [PATCH] Allow declaration of map and multimap iterator with incomplete mapped type. Patch from eugenis llvm-svn: 231119 --- libcxx/include/__tree | 60 ++++++++++++++-------- libcxx/include/map | 29 +++++++---- .../map/map.cons/default_recursive.pass.cpp | 8 +-- .../multimap.cons/default_recursive.pass.cpp | 29 +++++++++++ 4 files changed, 91 insertions(+), 35 deletions(-) create mode 100644 libcxx/test/std/containers/associative/multimap/multimap.cons/default_recursive.pass.cpp diff --git a/libcxx/include/__tree b/libcxx/include/__tree index d768b38..6da2416 100644 --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -614,8 +614,6 @@ class _LIBCPP_TYPE_VIS_ONLY __tree_iterator { 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 @@ public: {return pointer_traits::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(__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(__ptr_))); + return *this; + } _LIBCPP_INLINE_VISIBILITY __tree_iterator operator--(int) {__tree_iterator __t(*this); --(*this); return __t;} @@ -683,14 +685,6 @@ class _LIBCPP_TYPE_VIS_ONLY __tree_const_iterator { 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 @@ public: {return pointer_traits::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 +#else + rebind::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 +#else + rebind::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;} diff --git a/libcxx/include/map b/libcxx/include/map index 5c3969a..0b5eb20 100644 --- a/libcxx/include/map +++ b/libcxx/include/map @@ -644,14 +644,25 @@ struct __value_type #endif +template +struct __extract_key_value_types; + +template +struct __extract_key_value_types<__value_type<_Key, _Tp> > +{ + typedef _Key const __key_type; + typedef _Tp __mapped_type; +}; + template 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 typename _TreeIterator::value_type __value_type; + typedef typename __extract_key_value_types<__value_type>::__key_type __key_type; + typedef typename __extract_key_value_types<__value_type>::__mapped_type __mapped_type; public: typedef bidirectional_iterator_tag iterator_category; typedef pair<__key_type, __mapped_type> value_type; @@ -715,8 +726,9 @@ 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 typename _TreeIterator::value_type __value_type; + typedef typename __extract_key_value_types<__value_type>::__key_type __key_type; + typedef typename __extract_key_value_types<__value_type>::__mapped_type __mapped_type; public: typedef bidirectional_iterator_tag iterator_category; typedef pair<__key_type, __mapped_type> value_type; @@ -736,10 +748,9 @@ public: _LIBCPP_INLINE_VISIBILITY __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {} _LIBCPP_INLINE_VISIBILITY - __map_const_iterator( - __map_iterator __i) - _NOEXCEPT - : __i_(__i.__i_) {} + __map_const_iterator(__map_iterator< + typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT + : __i_(__i.__i_) {} _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __i_->__cc;} @@ -829,7 +840,7 @@ public: 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 iterator; + typedef __map_iterator iterator; typedef __map_const_iterator const_iterator; typedef _VSTD::reverse_iterator reverse_iterator; typedef _VSTD::reverse_iterator const_reverse_iterator; diff --git a/libcxx/test/std/containers/associative/map/map.cons/default_recursive.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/default_recursive.pass.cpp index 8b393d3..b4b7272 100644 --- a/libcxx/test/std/containers/associative/map/map.cons/default_recursive.pass.cpp +++ b/libcxx/test/std/containers/associative/map/map.cons/default_recursive.pass.cpp @@ -15,15 +15,15 @@ #include -#if !__has_feature(cxx_noexcept) - struct X { std::map m; + std::map::iterator i; + std::map::const_iterator ci; + std::map::reverse_iterator ri; + std::map::const_reverse_iterator cri; }; -#endif - int main() { } diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/default_recursive.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/default_recursive.pass.cpp new file mode 100644 index 0000000..08ca8a4 --- /dev/null +++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/default_recursive.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// class multimap + +// multimap(); + +#include + +struct X +{ + std::multimap m; + std::multimap::iterator i; + std::multimap::const_iterator ci; + std::multimap::reverse_iterator ri; + std::multimap::const_reverse_iterator cri; +}; + +int main() +{ +} -- 2.7.4