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

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@266491 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2016-04-15 23:27:27 +00:00
parent d5019333fa
commit 83c9dc1714
17 changed files with 1004 additions and 1018 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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>

View File

@@ -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

View File

@@ -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<> >();
}

View File

@@ -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<> >();
}

View File

@@ -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<> >();
}

View File

@@ -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<> >();
}

View File

@@ -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<> >();
}

View File

@@ -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<> >();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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<> >();
}

View File

@@ -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<> >();
}

View File

@@ -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<> >();
}

View File

@@ -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<> >();
}

View File

@@ -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