From 9fd9f84f480f1d260f6d6feb551b654a0d38ebfd Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Mon, 30 Sep 2013 19:08:22 +0000 Subject: [PATCH] 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. llvm-svn: 191692 --- libcxx/include/map | 156 ++++++++---------- libcxx/include/unordered_map | 153 ++++++++--------- .../associative/multimap/scary.pass.cpp | 24 +++ .../associative/multiset/scary.pass.cpp | 24 +++ .../unord/unord.multimap/scary.pass.cpp | 24 +++ .../unord/unord.multiset/scary.pass.cpp | 24 +++ 6 files changed, 234 insertions(+), 171 deletions(-) create mode 100644 libcxx/test/containers/associative/multimap/scary.pass.cpp create mode 100644 libcxx/test/containers/associative/multiset/scary.pass.cpp create mode 100644 libcxx/test/containers/unord/unord.multimap/scary.pass.cpp create mode 100644 libcxx/test/containers/unord/unord.multiset/scary.pass.cpp diff --git a/libcxx/include/map b/libcxx/include/map index 82a0a9c9a045..009e8e2162c5 100644 --- a/libcxx/include/map +++ b/libcxx/include/map @@ -575,6 +575,75 @@ template class multimap; template class __map_const_iterator; +#if __cplusplus >= 201103L + +template +union __value_type +{ + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef pair __nc_value_type; + + value_type __cc; + __nc_value_type __nc; + + template + _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 +struct __value_type +{ + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + + value_type __cc; + + _LIBCPP_INLINE_VISIBILITY + __value_type() {} + + template + _LIBCPP_INLINE_VISIBILITY + __value_type(const _A0& __a0) + : __cc(__a0) {} + + template + _LIBCPP_INLINE_VISIBILITY + __value_type(const _A0& __a0, const _A1& __a1) + : __cc(__a0, __a1) {} +}; + +#endif + template 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 - __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 - __value_type(const _A0& __a0) - : __cc(__a0) {} - - template - __value_type(const _A0& __a0, const _A1& __a1) - : __cc(__a0, __a1) {} - }; -#endif + typedef _VSTD::__value_type __value_type; typedef __map_value_compare __vc; typedef typename allocator_traits::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 - __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 - __value_type(const _A0& __a0) - : __cc(__a0) {} - - template - __value_type(const _A0& __a0, const _A1& __a1) - : __cc(__a0, __a1) {} - }; -#endif + typedef _VSTD::__value_type __value_type; typedef __map_value_compare __vc; typedef typename allocator_traits::template #ifndef _LIBCPP_HAS_NO_TEMPLATE_ALIASES diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map index e1a3f641c34d..78fee4811fad 100644 --- a/libcxx/include/unordered_map +++ b/libcxx/include/unordered_map @@ -525,6 +525,71 @@ public: } }; +#if __cplusplus >= 201103L + +template +union __hash_value_type +{ + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef pair __nc_value_type; + + value_type __cc; + __nc_value_type __nc; + + template + _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 +struct __hash_value_type +{ + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + + value_type __cc; + + _LIBCPP_INLINE_VISIBILITY + __hash_value_type() {} + + template + _LIBCPP_INLINE_VISIBILITY + __hash_value_type(const _A0& __a0) + : __cc(__a0) {} + + template + _LIBCPP_INLINE_VISIBILITY + __hash_value_type(const _A0& __a0, const _A1& __a1) + : __cc(__a0, __a1) {} +}; + +#endif + template 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 - __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 - __value_type(const _A0& __a0) - : __cc(__a0) {} - - template - __value_type(const _A0& __a0, const _A1& __a1) - : __cc(__a0, __a1) {} - }; -#endif + typedef __hash_value_type __value_type; typedef __unordered_map_hasher __hasher; typedef __unordered_map_equal __key_equal; typedef typename allocator_traits::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 - __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 - __value_type(const _A0& __a0) - : __cc(__a0) {} - - template - __value_type(const _A0& __a0, const _A1& __a1) - : __cc(__a0, __a1) {} - }; -#endif + typedef __hash_value_type __value_type; typedef __unordered_map_hasher __hasher; typedef __unordered_map_equal __key_equal; typedef typename allocator_traits::template diff --git a/libcxx/test/containers/associative/multimap/scary.pass.cpp b/libcxx/test/containers/associative/multimap/scary.pass.cpp new file mode 100644 index 000000000000..b99d9bc2df91 --- /dev/null +++ b/libcxx/test/containers/associative/multimap/scary.pass.cpp @@ -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. +// +//===----------------------------------------------------------------------===// + +// + +// class map class multimap + +// Extension: SCARY/N2913 iterator compatibility between map and multimap + +#include + +int main() +{ + typedef std::map M1; + typedef std::multimap M2; + M2::iterator i; + M1::iterator j = i; +} diff --git a/libcxx/test/containers/associative/multiset/scary.pass.cpp b/libcxx/test/containers/associative/multiset/scary.pass.cpp new file mode 100644 index 000000000000..f5ee32714e86 --- /dev/null +++ b/libcxx/test/containers/associative/multiset/scary.pass.cpp @@ -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. +// +//===----------------------------------------------------------------------===// + +// + +// class set class multiset + +// Extension: SCARY/N2913 iterator compatibility between set and multiset + +#include + +int main() +{ + typedef std::set M1; + typedef std::multiset M2; + M2::iterator i; + M1::iterator j = i; +} diff --git a/libcxx/test/containers/unord/unord.multimap/scary.pass.cpp b/libcxx/test/containers/unord/unord.multimap/scary.pass.cpp new file mode 100644 index 000000000000..e619a7a54294 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multimap/scary.pass.cpp @@ -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. +// +//===----------------------------------------------------------------------===// + +// + +// class unordered_map class unordered_multimap + +// Extension: SCARY/N2913 iterator compatibility between unordered_map and unordered_multimap + +#include + +int main() +{ + typedef std::unordered_map M1; + typedef std::unordered_multimap M2; + M2::iterator i; + M1::iterator j = i; +} diff --git a/libcxx/test/containers/unord/unord.multiset/scary.pass.cpp b/libcxx/test/containers/unord/unord.multiset/scary.pass.cpp new file mode 100644 index 000000000000..dfd144bb3170 --- /dev/null +++ b/libcxx/test/containers/unord/unord.multiset/scary.pass.cpp @@ -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. +// +//===----------------------------------------------------------------------===// + +// + +// class unordered_set class unordered_multiset + +// Extension: SCARY/N2913 iterator compatibility between unordered_set and unordered_multiset + +#include + +int main() +{ + typedef std::unordered_set M1; + typedef std::unordered_multiset M2; + M2::iterator i; + M1::iterator j = i; +}