diff options
| author | Eric Fiselier <eric@efcs.ca> | 2016-04-15 23:27:27 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2016-04-15 23:27:27 +0000 |
| commit | fa1f613f7ef938c9d91741141d74ef4fafba3902 (patch) | |
| tree | eb86af1f42bbd8ac33971cbcbfd0b5e082fdda17 | |
| parent | db6861e7dd5ba7b3ed59a92036a87ff9913c808a (diff) | |
| download | bcm5719-llvm-fa1f613f7ef938c9d91741141d74ef4fafba3902.tar.gz bcm5719-llvm-fa1f613f7ef938c9d91741141d74ef4fafba3902.zip | |
Extract key to avoid preemptive mallocs in insert/emplace in associative containers
Summary: This patch applies Duncan's work on __hash_table to __tree.
Reviewers: mclow.lists, dexonsmith
Subscribers: dexonsmith, cfe-commits
Differential Revision: http://reviews.llvm.org/D18637
llvm-svn: 266491
17 files changed, 1004 insertions, 1018 deletions
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index 16a0f5eb0fd..2ea1a305720 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -100,22 +100,6 @@ __next_hash_pow2(size_t __n) return size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1)); } -#ifndef _LIBCPP_CXX03_LANG -struct __extract_key_fail_tag {}; -struct __extract_key_self_tag {}; -struct __extract_key_first_tag {}; - -template <class _ValTy, class _Key, - class _RawValTy = typename __unconstref<_ValTy>::type> -struct __can_extract_key - : conditional<is_same<_RawValTy, _Key>::value, __extract_key_self_tag, - __extract_key_fail_tag>::type {}; - -template <class _Pair, class _Key, class _First, class _Second> -struct __can_extract_key<_Pair, _Key, pair<_First, _Second>> - : conditional<is_same<typename remove_const<_First>::type, _Key>::value, - __extract_key_first_tag, __extract_key_fail_tag>::type {}; -#endif template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table; diff --git a/libcxx/include/__tree b/libcxx/include/__tree index 314d5eb0234..eb6ff05c492 100644 --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -1064,16 +1064,85 @@ public: __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...); template <class... _Args> - pair<iterator, bool> __emplace_unique(_Args&&... __args); + pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); template <class... _Args> - iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args); + iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args); template <class... _Args> iterator __emplace_multi(_Args&&... __args); template <class... _Args> iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique(_Pp&& __x) { + return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> __emplace_unique(_Args&&... __args) { + return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { + return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { + return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + pair<iterator, bool> + __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { + return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique(const_iterator __p, _Pp&& __x) { + return __emplace_hint_unique_extract_key(__p, _VSTD::forward<_Pp>(__x), + __can_extract_key<_Pp, key_type>()); + } + + template <class... _Args> + _LIBCPP_INLINE_VISIBILITY + iterator __emplace_hint_unique(const_iterator __p, _Args&&... __args) { + return __emplace_hint_unique_impl(__p, _VSTD::forward<_Args>(__args)...); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_fail_tag) { + return __emplace_hint_unique_impl(__p, _VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_self_tag) { + return __emplace_hint_unique_key_args(__p, __x, _VSTD::forward<_Pp>(__x)); + } + + template <class _Pp> + _LIBCPP_INLINE_VISIBILITY + iterator + __emplace_hint_unique_extract_key(const_iterator __p, _Pp&& __x, __extract_key_first_tag) { + return __emplace_hint_unique_key_args(__p, __x.first, _VSTD::forward<_Pp>(__x)); + } + #else template <class _Key, class _Args> _LIBCPP_INLINE_VISIBILITY @@ -1989,7 +2058,7 @@ __tree<_Tp, _Compare, _Allocator>::__construct_node(_Args&& ...__args) template <class _Tp, class _Compare, class _Allocator> template <class... _Args> pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool> -__tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args) +__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); __node_base_pointer __parent; @@ -2008,7 +2077,7 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_unique(_Args&&... __args) template <class _Tp, class _Compare, class _Allocator> template <class... _Args> typename __tree<_Tp, _Compare, _Allocator>::iterator -__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique(const_iterator __p, _Args&&... __args) +__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) { __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); __node_base_pointer __parent; diff --git a/libcxx/include/__tuple b/libcxx/include/__tuple index 8c31759774d..09c68393aed 100644 --- a/libcxx/include/__tuple +++ b/libcxx/include/__tuple @@ -95,8 +95,6 @@ get(const tuple<_Tp...>&&) _NOEXCEPT; // pair specializations -template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair; - template <class _T1, class _T2> struct __tuple_like<pair<_T1, _T2> > : true_type {}; template <size_t _Ip, class _T1, class _T2> diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 6840ee23a4a..12e24b77bae 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -368,6 +368,8 @@ namespace std _LIBCPP_BEGIN_NAMESPACE_STD +template <class _T1, class _T2> struct _LIBCPP_TYPE_VIS_ONLY pair; + template <class> struct __void_t { typedef void type; }; @@ -4434,6 +4436,24 @@ template<class _Tp> constexpr bool negation_v = negation<_Tp>::value; # endif // _LIBCPP_HAS_NO_VARIADICS #endif // _LIBCPP_STD_VER > 14 +// These traits are used in __tree and __hash_table +#ifndef _LIBCPP_CXX03_LANG +struct __extract_key_fail_tag {}; +struct __extract_key_self_tag {}; +struct __extract_key_first_tag {}; + +template <class _ValTy, class _Key, + class _RawValTy = typename __unconstref<_ValTy>::type> +struct __can_extract_key + : conditional<is_same<_RawValTy, _Key>::value, __extract_key_self_tag, + __extract_key_fail_tag>::type {}; + +template <class _Pair, class _Key, class _First, class _Second> +struct __can_extract_key<_Pair, _Key, pair<_First, _Second>> + : conditional<is_same<typename remove_const<_First>::type, _Key>::value, + __extract_key_first_tag, __extract_key_fail_tag>::type {}; +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_TYPE_TRAITS diff --git a/libcxx/test/std/containers/associative/map/map.modifiers/insert_allocator_requirements.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_allocator_requirements.pass.cpp deleted file mode 100644 index adc5b312b9f..00000000000 --- a/libcxx/test/std/containers/associative/map/map.modifiers/insert_allocator_requirements.pass.cpp +++ /dev/null @@ -1,137 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// insert(...); - -// UNSUPPORTED: c++98, c++03 - -#include <map> -#include <iostream> -#include <cassert> - -#include "test_macros.h" -#include "count_new.hpp" -#include "container_test_types.h" - -template <class Arg> -void PrintInfo(int line, Arg&& arg) -{ - std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; -} -#define PRINT(msg) PrintInfo(__LINE__, msg) - -template <class Container> -void testContainerInsert() -{ - typedef typename Container::value_type ValueTp; - typedef Container C; - typedef std::pair<typename C::iterator, bool> R; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::insert(const value_type&)"); - Container c; - const ValueTp v(42, 1); - cc->expect<const ValueTp&>(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42, 1); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&)"); - Container c; - ValueTp v(42, 1); - cc->expect<const ValueTp&>(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42, 1); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&&)"); - Container c; - ValueTp v(42, 1); - cc->expect<ValueTp&&>(); - assert(c.insert(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42, 1); - assert(c.insert(std::move(v2)).second == false); - } - } - { - PRINT("Testing C::insert(std::initializer_list<ValueTp>)"); - Container c; - std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) }; - cc->expect<ValueTp const&>(2); - c.insert(il); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(il); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); - Container c; - const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); - Container c; - ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - cc->expect<ValueTp&&>(3); - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), - std::move_iterator<ValueTp*>(std::end(ValueList))); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp ValueList2[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)), - std::move_iterator<ValueTp*>(std::end(ValueList2))); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); - Container c; - ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } -} - - -int main() -{ - testContainerInsert<TCT::map<> >(); -} diff --git a/libcxx/test/std/containers/associative/map/map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp b/libcxx/test/std/containers/associative/map/map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp new file mode 100644 index 00000000000..9eae6281042 --- /dev/null +++ b/libcxx/test/std/containers/associative/map/map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// insert(...); +// emplace(...); +// emplace_hint(...); + +// UNSUPPORTED: c++98, c++03 + +#include <map> + +#include "container_test_types.h" +#include "../../../map_allocator_requirement_test_templates.h" + +int main() +{ + testMapInsert<TCT::map<> >(); + testMapEmplace<TCT::map<> >(); + testMapEmplaceHint<TCT::map<> >(); +} diff --git a/libcxx/test/std/containers/associative/multimap/multimap.modifiers/insert_allocator_requirements.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.modifiers/insert_allocator_requirements.pass.cpp index 8e3677dd7d0..d421de31767 100644 --- a/libcxx/test/std/containers/associative/multimap/multimap.modifiers/insert_allocator_requirements.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/multimap.modifiers/insert_allocator_requirements.pass.cpp @@ -16,88 +16,12 @@ // UNSUPPORTED: c++98, c++03 #include <map> -#include <iostream> -#include <cassert> -#include "test_macros.h" -#include "count_new.hpp" #include "container_test_types.h" - -template <class Arg> -void PrintInfo(int line, Arg&& arg) -{ - std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; -} -#define PRINT(msg) PrintInfo(__LINE__, msg) - -template <class Container> -void testContainerInsert() -{ - typedef typename Container::value_type ValueTp; - typedef Container C; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::insert(const value_type&)"); - Container c; - const ValueTp v(42, 1); - cc->expect<const ValueTp&>(); - c.insert(v); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(value_type&)"); - Container c; - ValueTp v(42, 1); - cc->expect<ValueTp&>(); - c.insert(v); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(value_type&&)"); - Container c; - ValueTp v(42, 1); - cc->expect<ValueTp&&>(); - c.insert(std::move(v)); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(std::initializer_list<ValueTp>)"); - Container c; - std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) }; - cc->expect<ValueTp const&>(2); - c.insert(il); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); - Container c; - const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); - Container c; - ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - cc->expect<ValueTp&&>(3); - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), - std::move_iterator<ValueTp*>(std::end(ValueList))); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); - Container c; - ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - cc->expect<ValueTp&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - } -} +#include "../../../map_allocator_requirement_test_templates.h" int main() { - testContainerInsert<TCT::multimap<> >(); + testMultimapInsert<TCT::multimap<> >(); } diff --git a/libcxx/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp b/libcxx/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp index a85c77625b4..a280d10d5ab 100644 --- a/libcxx/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp +++ b/libcxx/test/std/containers/associative/multiset/insert_allocator_requirements.pass.cpp @@ -16,87 +16,11 @@ // UNSUPPORTED: c++98, c++03 #include <set> -#include <iostream> -#include <cassert> -#include "test_macros.h" -#include "count_new.hpp" #include "container_test_types.h" - -template <class Arg> -void PrintInfo(int line, Arg&& arg) -{ - std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; -} -#define PRINT(...) PrintInfo(__LINE__, __VA_ARGS__) - -template <class Container> -void testContainerInsert() -{ - typedef typename Container::value_type ValueTp; - typedef Container C; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::insert(const value_type&)"); - Container c; - const ValueTp v(42); - cc->expect<const ValueTp&>(); - c.insert(v); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(value_type&)"); - Container c; - ValueTp v(42); - cc->expect<const ValueTp&>(); - c.insert(v); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(value_type&&)"); - Container c; - ValueTp v(42); - cc->expect<ValueTp&&>(); - c.insert(std::move(v)); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(std::initializer_list<ValueTp>)"); - Container c; - std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) }; - cc->expect<ValueTp const&>(2); - c.insert(il); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); - Container c; - const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); - Container c; - ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - cc->expect<ValueTp&&>(3); - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), - std::move_iterator<ValueTp*>(std::end(ValueList))); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); - Container c; - ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - cc->expect<ValueTp&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - } -} +#include "../../set_allocator_requirement_test_templates.h" int main() { - testContainerInsert<TCT::multiset<> >(); + testMultisetInsert<TCT::multiset<> >(); } diff --git a/libcxx/test/std/containers/associative/set/insert_allocator_requirements.pass.cpp b/libcxx/test/std/containers/associative/set/insert_allocator_requirements.pass.cpp deleted file mode 100644 index f0836692408..00000000000 --- a/libcxx/test/std/containers/associative/set/insert_allocator_requirements.pass.cpp +++ /dev/null @@ -1,137 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 - -// insert(...) - -// UNSUPPORTED: c++98, c++03 - -#include <set> -#include <iostream> -#include <cassert> - -#include "test_macros.h" -#include "count_new.hpp" -#include "container_test_types.h" - -template <class Arg> -void PrintInfo(int line, Arg&& arg) -{ - std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; -} -#define PRINT(msg) PrintInfo(__LINE__, msg) - -template <class Container> -void testContainerInsert() -{ - typedef typename Container::value_type ValueTp; - typedef Container C; - typedef std::pair<typename C::iterator, bool> R; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::insert(const value_type&)"); - Container c; - const ValueTp v(42); - cc->expect<const ValueTp&>(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&)"); - Container c; - ValueTp v(42); - cc->expect<const ValueTp&>(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&&)"); - Container c; - ValueTp v(42); - cc->expect<ValueTp&&>(); - assert(c.insert(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42); - assert(c.insert(std::move(v2)).second == false); - } - } - { - PRINT("Testing C::insert(std::initializer_list<ValueTp>)"); - Container c; - std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) }; - cc->expect<ValueTp const&>(2); - c.insert(il); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(il); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); - Container c; - const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); - Container c; - ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - cc->expect<ValueTp&&>(3); - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), - std::move_iterator<ValueTp*>(std::end(ValueList))); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp ValueList2[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)), - std::move_iterator<ValueTp*>(std::end(ValueList2))); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); - Container c; - ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } -} - - -int main() -{ - testContainerInsert<TCT::set<> >(); -} diff --git a/libcxx/test/std/containers/associative/set/insert_and_emplace_allocator_requirements.pass.cpp b/libcxx/test/std/containers/associative/set/insert_and_emplace_allocator_requirements.pass.cpp new file mode 100644 index 00000000000..b14340b1d76 --- /dev/null +++ b/libcxx/test/std/containers/associative/set/insert_and_emplace_allocator_requirements.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. +// +//===----------------------------------------------------------------------===// + +// <set> + +// class set + +// insert(...) +// emplace(...) +// emplace_hint(...) + +// UNSUPPORTED: c++98, c++03 + +#include <set> +#include "container_test_types.h" +#include "../../set_allocator_requirement_test_templates.h" + +int main() +{ + testSetInsert<TCT::set<> >(); + testSetEmplace<TCT::set<> >(); + testSetEmplaceHint<TCT::set<> >(); +} diff --git a/libcxx/test/std/containers/map_allocator_requirement_test_templates.h b/libcxx/test/std/containers/map_allocator_requirement_test_templates.h new file mode 100644 index 00000000000..b5958f70da2 --- /dev/null +++ b/libcxx/test/std/containers/map_allocator_requirement_test_templates.h @@ -0,0 +1,419 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// +#ifndef MAP_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H +#define MAP_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H + +// <map> +// <unordered_map> + +// class map +// class unordered_map + +// insert(...); +// emplace(...); +// emplace_hint(...); + +// UNSUPPORTED: c++98, c++03 + +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" +#include "container_test_types.h" +#include "assert_checkpoint.h" + + +template <class Container> +void testMapInsert() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + typedef std::pair<typename C::iterator, bool> R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::insert(const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.insert(v2).second == false); + } + } + { + CHECKPOINT("Testing C::insert(value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.insert(v2).second == false); + } + } + { + CHECKPOINT("Testing C::insert(value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&&>(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.insert(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::insert(const value_type&&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.insert(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)"); + Container c; + std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) }; + cc->expect<ValueTp const&>(2); + c.insert(il); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(il); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); + Container c; + const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); + Container c; + ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + cc->expect<ValueTp&&>(3); + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), + std::move_iterator<ValueTp*>(std::end(ValueList))); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp ValueList2[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)), + std::move_iterator<ValueTp*>(std::end(ValueList2))); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); + Container c; + ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } +} + +template <class Container> +void testMapEmplace() +{ + typedef typename Container::value_type ValueTp; + typedef typename Container::key_type Key; + typedef typename Container::mapped_type Mapped; + typedef typename std::pair<Key, Mapped> NonConstKeyPair; + typedef Container C; + typedef std::pair<typename C::iterator, bool> R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::emplace(const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.emplace(v2).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&>(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.emplace(v2).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&&>(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + assert(c.emplace(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(const value_type&&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&&>(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + assert(c.emplace(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(pair<Key, Mapped> const&)"); + Container c; + const NonConstKeyPair v(42, 1); + cc->expect<const NonConstKeyPair&>(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const NonConstKeyPair v2(42, 1); + assert(c.emplace(v2).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(pair<Key, Mapped> &&)"); + Container c; + NonConstKeyPair v(42, 1); + cc->expect<NonConstKeyPair&&>(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + NonConstKeyPair v2(42, 1); + assert(c.emplace(std::move(v2)).second == false); + } + } +} + + +template <class Container> +void testMapEmplaceHint() +{ + typedef typename Container::value_type ValueTp; + typedef typename Container::key_type Key; + typedef typename Container::mapped_type Mapped; + typedef typename std::pair<Key, Mapped> NonConstKeyPair; + typedef Container C; + typedef typename C::iterator It; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::emplace_hint(p, const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&>(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&&>(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, const value_type&&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&&>(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, pair<Key, Mapped> const&)"); + Container c; + const NonConstKeyPair v(42, 1); + cc->expect<const NonConstKeyPair&>(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const NonConstKeyPair v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, pair<Key, Mapped>&&)"); + Container c; + NonConstKeyPair v(42, 1); + cc->expect<NonConstKeyPair&&>(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + NonConstKeyPair v2(42, 1); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } +} + + +template <class Container> +void testMultimapInsert() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::insert(const value_type&)"); + Container c; + const ValueTp v(42, 1); + cc->expect<const ValueTp&>(); + c.insert(v); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(value_type&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&>(); + c.insert(v); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(value_type&&)"); + Container c; + ValueTp v(42, 1); + cc->expect<ValueTp&&>(); + c.insert(std::move(v)); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)"); + Container c; + std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) }; + cc->expect<ValueTp const&>(2); + c.insert(il); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); + Container c; + const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); + Container c; + ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + cc->expect<ValueTp&&>(3); + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), + std::move_iterator<ValueTp*>(std::end(ValueList))); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); + Container c; + ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; + cc->expect<ValueTp&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + } +} + +#endif
\ No newline at end of file diff --git a/libcxx/test/std/containers/set_allocator_requirement_test_templates.h b/libcxx/test/std/containers/set_allocator_requirement_test_templates.h new file mode 100644 index 00000000000..fe72bf8507b --- /dev/null +++ b/libcxx/test/std/containers/set_allocator_requirement_test_templates.h @@ -0,0 +1,356 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// +#ifndef SET_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H +#define SET_ALLOCATOR_REQUIREMENT_TEST_TEMPLATES_H + +// <set> +// <unordered_set> + +// class set +// class unordered_set + +// insert(...); +// emplace(...); +// emplace_hint(...); + + +#include <cassert> + +#include "test_macros.h" +#include "count_new.hpp" +#include "container_test_types.h" +#include "assert_checkpoint.h" + + +template <class Container> +void testSetInsert() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + typedef std::pair<typename C::iterator, bool> R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::insert(const value_type&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&>(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.insert(v2).second == false); + } + } + { + CHECKPOINT("Testing C::insert(value_type&)"); + Container c; + ValueTp v(42); + cc->expect<const ValueTp&>(); + assert(c.insert(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.insert(v2).second == false); + } + } + { + CHECKPOINT("Testing C::insert(value_type&&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&&>(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.insert(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::insert(const value_type&&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&>(); + assert(c.insert(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.insert(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)"); + Container c; + std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) }; + cc->expect<ValueTp const&>(2); + c.insert(il); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(il); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); + Container c; + const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); + Container c; + ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + cc->expect<ValueTp&&>(3); + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), + std::move_iterator<ValueTp*>(std::end(ValueList))); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp ValueList2[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)), + std::move_iterator<ValueTp*>(std::end(ValueList2))); + } + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); + Container c; + ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + c.insert(std::begin(ValueList), std::end(ValueList)); + } + } +} + + +template <class Container> +void testSetEmplace() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + typedef std::pair<typename C::iterator, bool> R; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::emplace(const value_type&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&>(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.emplace(v2).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(value_type&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&>(); + assert(c.emplace(v).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.emplace(v2).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(value_type&&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&&>(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + assert(c.emplace(std::move(v2)).second == false); + } + } + { + CHECKPOINT("Testing C::emplace(const value_type&&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&&>(); + assert(c.emplace(std::move(v)).second); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + assert(c.emplace(std::move(v2)).second == false); + } + } +} + + +template <class Container> +void testSetEmplaceHint() +{ + typedef typename Container::value_type ValueTp; + + typedef Container C; + typedef typename C::iterator It; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::emplace_hint(p, const value_type&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&>(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, value_type&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&>(); + It ret = c.emplace_hint(c.end(), v); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), v2); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, value_type&&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&&>(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } + { + CHECKPOINT("Testing C::emplace_hint(p, const value_type&&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&&>(); + It ret = c.emplace_hint(c.end(), std::move(v)); + assert(ret != c.end()); + assert(c.size() == 1); + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + const ValueTp v2(42); + It ret2 = c.emplace_hint(c.begin(), std::move(v2)); + assert(&(*ret2) == &(*ret)); + assert(c.size() == 1); + } + } +} + + +template <class Container> +void testMultisetInsert() +{ + typedef typename Container::value_type ValueTp; + typedef Container C; + ConstructController* cc = getConstructController(); + cc->reset(); + { + CHECKPOINT("Testing C::insert(const value_type&)"); + Container c; + const ValueTp v(42); + cc->expect<const ValueTp&>(); + c.insert(v); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(value_type&)"); + Container c; + ValueTp v(42); + cc->expect<const ValueTp&>(); + c.insert(v); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(value_type&&)"); + Container c; + ValueTp v(42); + cc->expect<ValueTp&&>(); + c.insert(std::move(v)); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)"); + Container c; + std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) }; + cc->expect<ValueTp const&>(2); + c.insert(il); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); + Container c; + const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) }; + cc->expect<ValueTp const&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); + Container c; + ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + cc->expect<ValueTp&&>(3); + c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), + std::move_iterator<ValueTp*>(std::end(ValueList))); + assert(!cc->unchecked()); + } + { + CHECKPOINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); + Container c; + ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; + cc->expect<ValueTp&>(3); + c.insert(std::begin(ValueList), std::end(ValueList)); + assert(!cc->unchecked()); + } +} + + + +#endif
\ No newline at end of file diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp index 1268051f178..5ee206a85ed 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp @@ -12,233 +12,18 @@ // class unordered_map // insert(...); +// emplace(...); // UNSUPPORTED: c++98, c++03 #include <unordered_map> -#include <iostream> -#include <cassert> -#include "test_macros.h" -#include "count_new.hpp" #include "container_test_types.h" - -template <class Arg> -void PrintInfo(int line, Arg&& arg) -{ - std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; -} -#define PRINT(msg) PrintInfo(__LINE__, msg) - -template <class Container> -void testContainerInsert() -{ - typedef typename Container::value_type ValueTp; - typedef Container C; - typedef std::pair<typename C::iterator, bool> R; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::insert(const value_type&)"); - Container c; - const ValueTp v(42, 1); - cc->expect<const ValueTp&>(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42, 1); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&)"); - Container c; - ValueTp v(42, 1); - cc->expect<const ValueTp&>(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42, 1); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&&)"); - Container c; - ValueTp v(42, 1); - cc->expect<ValueTp&&>(); - assert(c.insert(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42, 1); - assert(c.insert(std::move(v2)).second == false); - } - } - { - PRINT("Testing C::insert(const value_type&&)"); - Container c; - const ValueTp v(42, 1); - cc->expect<const ValueTp&>(); - assert(c.insert(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42, 1); - assert(c.insert(std::move(v2)).second == false); - } - } - { - PRINT("Testing C::insert(std::initializer_list<ValueTp>)"); - Container c; - std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) }; - cc->expect<ValueTp const&>(2); - c.insert(il); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(il); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); - Container c; - const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); - Container c; - ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - cc->expect<ValueTp&&>(3); - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), - std::move_iterator<ValueTp*>(std::end(ValueList))); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp ValueList2[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)), - std::move_iterator<ValueTp*>(std::end(ValueList2))); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); - Container c; - ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } -} - - -template <class Container> -void testContainerEmplace() -{ - typedef typename Container::value_type ValueTp; - typedef typename Container::key_type Key; - typedef typename Container::mapped_type Mapped; - typedef typename std::pair<Key, Mapped> NonConstKeyPair; - typedef Container C; - typedef std::pair<typename C::iterator, bool> R; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::emplace(const value_type&)"); - Container c; - const ValueTp v(42, 1); - cc->expect<const ValueTp&>(); - assert(c.emplace(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42, 1); - assert(c.emplace(v2).second == false); - } - } - { - PRINT("Testing C::emplace(value_type&)"); - Container c; - ValueTp v(42, 1); - cc->expect<ValueTp&>(); - assert(c.emplace(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42, 1); - assert(c.emplace(v2).second == false); - } - } - { - PRINT("Testing C::emplace(value_type&&)"); - Container c; - ValueTp v(42, 1); - cc->expect<ValueTp&&>(); - assert(c.emplace(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42, 1); - assert(c.emplace(std::move(v2)).second == false); - } - } - { - PRINT("Testing C::emplace(const value_type&&)"); - Container c; - const ValueTp v(42, 1); - cc->expect<const ValueTp&&>(); - assert(c.emplace(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42, 1); - assert(c.emplace(std::move(v2)).second == false); - } - } - { - PRINT("Testing C::emplace(pair<Key, Mapped> const&)"); - Container c; - const NonConstKeyPair v(42, 1); - cc->expect<const NonConstKeyPair&>(); - assert(c.emplace(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const NonConstKeyPair v2(42, 1); - assert(c.emplace(v2).second == false); - } - } - { - PRINT("Testing C::emplace(pair<Key, Mapped> &&)"); - Container c; - NonConstKeyPair v(42, 1); - cc->expect<NonConstKeyPair&&>(); - assert(c.emplace(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - NonConstKeyPair v2(42, 1); - assert(c.emplace(std::move(v2)).second == false); - } - } -} - +#include "../../../map_allocator_requirement_test_templates.h" int main() { - testContainerInsert<TCT::unordered_map<> >(); - testContainerEmplace<TCT::unordered_map<> >(); + testMapInsert<TCT::unordered_map<> >(); + testMapEmplace<TCT::unordered_map<> >(); } diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_allocator_requirements.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_allocator_requirements.pass.cpp index 793419a6580..1145eb99091 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_allocator_requirements.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_allocator_requirements.pass.cpp @@ -16,88 +16,11 @@ // UNSUPPORTED: c++98, c++03 #include <unordered_map> -#include <iostream> -#include <cassert> -#include "test_macros.h" -#include "count_new.hpp" #include "container_test_types.h" - -template <class Arg> -void PrintInfo(int line, Arg&& arg) -{ - std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; -} -#define PRINT(msg) PrintInfo(__LINE__, msg) - -template <class Container> -void testContainerInsert() -{ - typedef typename Container::value_type ValueTp; - typedef Container C; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::insert(const value_type&)"); - Container c; - const ValueTp v(42, 1); - cc->expect<const ValueTp&>(); - c.insert(v); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(value_type&)"); - Container c; - ValueTp v(42, 1); - cc->expect<ValueTp&>(); - c.insert(v); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(value_type&&)"); - Container c; - ValueTp v(42, 1); - cc->expect<ValueTp&&>(); - c.insert(std::move(v)); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(std::initializer_list<ValueTp>)"); - Container c; - std::initializer_list<ValueTp> il = { ValueTp(1, 1), ValueTp(2, 1) }; - cc->expect<ValueTp const&>(2); - c.insert(il); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); - Container c; - const ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); - Container c; - ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - cc->expect<ValueTp&&>(3); - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), - std::move_iterator<ValueTp*>(std::end(ValueList))); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); - Container c; - ValueTp ValueList[] = { ValueTp(1, 1), ValueTp(2, 1) , ValueTp(3, 1) }; - cc->expect<ValueTp&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - } -} - +#include "../../../map_allocator_requirement_test_templates.h" int main() { - testContainerInsert<TCT::unordered_multimap<> >(); + testMultimapInsert<TCT::unordered_multimap<> >(); } diff --git a/libcxx/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp index 791d7dd4604..ad7bc043a5b 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/insert_allocator_requirements.pass.cpp @@ -16,87 +16,10 @@ // UNSUPPORTED: c++98, c++03 #include <unordered_set> -#include <iostream> -#include <cassert> - -#include "test_macros.h" -#include "count_new.hpp" #include "container_test_types.h" - -template <class Arg> -void PrintInfo(int line, Arg&& arg) -{ - std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; -} -#define PRINT(msg) PrintInfo(__LINE__, msg) - -template <class Container> -void testContainerInsert() -{ - typedef typename Container::value_type ValueTp; - typedef Container C; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::insert(const value_type&)"); - Container c; - const ValueTp v(42); - cc->expect<const ValueTp&>(); - c.insert(v); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(value_type&)"); - Container c; - ValueTp v(42); - cc->expect<const ValueTp&>(); - c.insert(v); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(value_type&&)"); - Container c; - ValueTp v(42); - cc->expect<ValueTp&&>(); - c.insert(std::move(v)); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(std::initializer_list<ValueTp>)"); - Container c; - std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) }; - cc->expect<ValueTp const&>(2); - c.insert(il); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); - Container c; - const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); - Container c; - ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - cc->expect<ValueTp&&>(3); - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), - std::move_iterator<ValueTp*>(std::end(ValueList))); - assert(!cc->unchecked()); - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); - Container c; - ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - cc->expect<ValueTp&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - } -} +#include "../../set_allocator_requirement_test_templates.h" int main() { - testContainerInsert<TCT::unordered_multiset<> >(); + testMultisetInsert<TCT::unordered_multiset<> >(); } diff --git a/libcxx/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp b/libcxx/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp index 05c2d0a0bc4..e85e94538e7 100644 --- a/libcxx/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp @@ -17,199 +17,13 @@ // UNSUPPORTED: c++98, c++03 #include <unordered_set> -#include <iostream> -#include <cassert> -#include "test_macros.h" -#include "count_new.hpp" #include "container_test_types.h" - -template <class Arg> -void PrintInfo(int line, Arg&& arg) -{ - std::cout << "In " << __FILE__ << ":" << line << ":\n " << arg << "\n" << std::endl; -} -#define PRINT(msg) PrintInfo(__LINE__, msg) - -template <class Container> -void testContainerInsert() -{ - typedef typename Container::value_type ValueTp; - typedef Container C; - typedef std::pair<typename C::iterator, bool> R; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::insert(const value_type&)"); - Container c; - const ValueTp v(42); - cc->expect<const ValueTp&>(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&)"); - Container c; - ValueTp v(42); - cc->expect<const ValueTp&>(); - assert(c.insert(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42); - assert(c.insert(v2).second == false); - } - } - { - PRINT("Testing C::insert(value_type&&)"); - Container c; - ValueTp v(42); - cc->expect<ValueTp&&>(); - assert(c.insert(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42); - assert(c.insert(std::move(v2)).second == false); - } - } - { - PRINT("Testing C::insert(const value_type&&)"); - Container c; - const ValueTp v(42); - cc->expect<const ValueTp&>(); - assert(c.insert(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42); - assert(c.insert(std::move(v2)).second == false); - } - } - { - PRINT("Testing C::insert(std::initializer_list<ValueTp>)"); - Container c; - std::initializer_list<ValueTp> il = { ValueTp(1), ValueTp(2) }; - cc->expect<ValueTp const&>(2); - c.insert(il); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(il); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type const&"); - Container c; - const ValueTp ValueList[] = { ValueTp(1), ValueTp(2), ValueTp(3) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&&"); - Container c; - ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - cc->expect<ValueTp&&>(3); - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList)), - std::move_iterator<ValueTp*>(std::end(ValueList))); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp ValueList2[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - c.insert(std::move_iterator<ValueTp*>(std::begin(ValueList2)), - std::move_iterator<ValueTp*>(std::end(ValueList2))); - } - } - { - PRINT("Testing C::insert(Iter, Iter) for *Iter = value_type&"); - Container c; - ValueTp ValueList[] = { ValueTp(1), ValueTp(2) , ValueTp(3) }; - cc->expect<ValueTp const&>(3); - c.insert(std::begin(ValueList), std::end(ValueList)); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - c.insert(std::begin(ValueList), std::end(ValueList)); - } - } -} - - -template <class Container> -void testContainerEmplace() -{ - typedef typename Container::value_type ValueTp; - typedef Container C; - typedef std::pair<typename C::iterator, bool> R; - ConstructController* cc = getConstructController(); - cc->reset(); - { - PRINT("Testing C::emplace(const value_type&)"); - Container c; - const ValueTp v(42); - cc->expect<const ValueTp&>(); - assert(c.emplace(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42); - assert(c.emplace(v2).second == false); - } - } - { - PRINT("Testing C::emplace(value_type&)"); - Container c; - ValueTp v(42); - cc->expect<ValueTp&>(); - assert(c.emplace(v).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42); - assert(c.emplace(v2).second == false); - } - } - { - PRINT("Testing C::emplace(value_type&&)"); - Container c; - ValueTp v(42); - cc->expect<ValueTp&&>(); - assert(c.emplace(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - ValueTp v2(42); - assert(c.emplace(std::move(v2)).second == false); - } - } - { - PRINT("Testing C::emplace(const value_type&&)"); - Container c; - const ValueTp v(42); - cc->expect<const ValueTp&&>(); - assert(c.emplace(std::move(v)).second); - assert(!cc->unchecked()); - { - DisableAllocationGuard g; - const ValueTp v2(42); - assert(c.emplace(std::move(v2)).second == false); - } - } -} +#include "../../set_allocator_requirement_test_templates.h" int main() { - testContainerInsert<TCT::unordered_set<> >(); - testContainerEmplace<TCT::unordered_set<> >(); + testSetInsert<TCT::unordered_set<> >(); + testSetEmplace<TCT::unordered_set<> >(); } diff --git a/libcxx/test/support/assert_checkpoint.h b/libcxx/test/support/assert_checkpoint.h new file mode 100644 index 00000000000..eea78efc39c --- /dev/null +++ b/libcxx/test/support/assert_checkpoint.h @@ -0,0 +1,62 @@ +#ifndef SUPPORT_ASSERT_CHECKPOINT_H +#define SUPPORT_ASSERT_CHECKPOINT_H + +#include <csignal> +#include <iostream> +#include <cstdlib> + +struct Checkpoint { + const char* file; + const char* func; + int line; + const char* msg; + + template <class Stream> + void print(Stream& s) const { + if (!file) { + s << "NO CHECKPOINT\n"; + return; + } + s << file << ":" << line << " " << func << ": Checkpoint"; + if (msg) + s << " '" << msg << "'"; + s << std::endl; + } +}; + +inline Checkpoint& globalCheckpoint() { + static Checkpoint C; + return C; +} + +inline void clearCheckpoint() { + globalCheckpoint() = Checkpoint{0}; +} + +#define CHECKPOINT(msg) globalCheckpoint() = Checkpoint{__FILE__, __PRETTY_FUNCTION__, __LINE__, msg} + +inline void checkpointSignalHandler(int signal) { + if (signal == SIGABRT) { + globalCheckpoint().print(std::cerr); + } else { + std::cerr << "Unexpected signal " << signal << " received\n"; + } + std::_Exit(EXIT_FAILURE); +} + +inline bool initCheckpointHandler() { + typedef void(*HandlerT)(int); + static bool isInit = false; + if (isInit) return true; + HandlerT prev_h = std::signal(SIGABRT, checkpointSignalHandler); + if (prev_h == SIG_ERR) { + std::cerr << "Setup failed.\n"; + std::_Exit(EXIT_FAILURE); + } + isInit = true; + return false; +} + +static bool initDummy = initCheckpointHandler(); + +#endif |

