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;
template <class _NodePtr> class _LIBCPP_TYPE_VIS_ONLY __hash_iterator;
typedef typename _NodeTypes::__node_value_type __node_value_type;
typedef typename _NodeTypes::__container_value_type __container_value_type;
+ typedef typename _NodeTypes::key_type key_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename __alloc_traits::pointer pointer;
#ifndef _LIBCPP_CXX03_LANG
template <class _Key, class ..._Args>
+ _LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> __emplace_unique_key_args(_Key const& __k, _Args&&... __args);
template <class... _Args>
- pair<iterator, bool> __emplace_unique(_Args&&... __args);
+ _LIBCPP_INLINE_VISIBILITY
+ pair<iterator, bool> __emplace_unique_impl(_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... _Args>
+ _LIBCPP_INLINE_VISIBILITY
iterator __emplace_multi(_Args&&... __args);
template <class... _Args>
+ _LIBCPP_INLINE_VISIBILITY
iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args);
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class... _Args>
pair<typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator, bool>
-__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique(_Args&&... __args)
+__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args)
{
__node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
pair<iterator, bool> __r = __node_insert_unique(__h.get());
+++ /dev/null
-//===----------------------------------------------------------------------===//
-//
-// 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.
-//
-//===----------------------------------------------------------------------===//
-
-// Check that we don't allocate when trying to insert a duplicate value into a
-// unordered_set. See PR12999 http://llvm.org/bugs/show_bug.cgi?id=12999
-
-#include <cassert>
-#include <unordered_set>
-#include "count_new.hpp"
-#include "MoveOnly.h"
-
-int main()
-{
- {
- std::unordered_set<int> s;
- assert(globalMemCounter.checkNewCalledEq(0));
-
- for(int i=0; i < 100; ++i)
- s.insert(3);
-
- assert(s.size() == 1);
- assert(s.count(3) == 1);
- assert(globalMemCounter.checkNewCalledEq(2));
- }
- assert(globalMemCounter.checkOutstandingNewEq(0));
- globalMemCounter.reset();
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
- {
- std::unordered_set<MoveOnly> s;
- assert(globalMemCounter.checkNewCalledEq(0));
-
- for(int i=0; i<100; i++)
- s.insert(MoveOnly(3));
-
- assert(s.size() == 1);
- assert(s.count(MoveOnly(3)) == 1);
- assert(globalMemCounter.checkNewCalledEq(2));
- }
- assert(globalMemCounter.checkOutstandingNewEq(0));
- globalMemCounter.reset();
-#endif
-}
}
}
{
+ 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) };
}
+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);
+ }
+ }
+}
+
+
int main()
{
testContainerInsert<TCT::unordered_map<> >();
+ testContainerEmplace<TCT::unordered_map<> >();
}
// class unordered_set
// insert(...)
+// emplace(...)
// UNSUPPORTED: c++98, c++03
}
}
{
+ 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) };
}
+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);
+ }
+ }
+}
+
+
int main()
{
testContainerInsert<TCT::unordered_set<> >();
+ testContainerEmplace<TCT::unordered_set<> >();
}