Fix LWG issue 2345 - Add insert(value_type&&)

llvm-svn: 266585
This commit is contained in:
Eric Fiselier 2016-04-18 01:40:45 +00:00
parent 99c224787b
commit 7a9f500fcb
21 changed files with 784 additions and 636 deletions

View File

@ -1076,9 +1076,7 @@ public:
insert(const_iterator __p, const value_type& __v) insert(const_iterator __p, const value_type& __v)
{return __tree_.__insert_unique(__p.__i_, __v);} {return __tree_.__insert_unique(__p.__i_, __v);}
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) #ifndef _LIBCPP_CXX03_LANG
// TODO(EricWF): These functions are C++17 only but they should probably
// be exposed in C++11.
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> pair<iterator, bool>
insert(value_type&& __v) {return __tree_.__insert_unique(_VSTD::move(__v));} insert(value_type&& __v) {return __tree_.__insert_unique(_VSTD::move(__v));}
@ -1787,6 +1785,14 @@ public:
iterator insert(const_iterator __pos, _Pp&& __p) iterator insert(const_iterator __pos, _Pp&& __p)
{return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));} {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));}
_LIBCPP_INLINE_VISIBILITY
iterator insert(value_type&& __v)
{return __tree_.__insert_multi(_VSTD::move(__v));}
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __p, value_type&& __v)
{return __tree_.__insert_multi(__p.__i_, _VSTD::move(__v));}
#endif // _LIBCPP_CXX03_LANG #endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
@ -1796,18 +1802,6 @@ public:
iterator insert(const_iterator __p, const value_type& __v) iterator insert(const_iterator __p, const value_type& __v)
{return __tree_.__insert_multi(__p.__i_, __v);} {return __tree_.__insert_multi(__p.__i_, __v);}
#if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
// TODO(EricWF): These functions are C++17 only but they should probably
// be exposed in C++11.
_LIBCPP_INLINE_VISIBILITY
iterator insert(value_type&& __v)
{return __tree_.__insert_multi(_VSTD::move(__v));}
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __p, value_type&& __v)
{return __tree_.__insert_multi(__p.__i_, _VSTD::move(__v));}
#endif
template <class _InputIterator> template <class _InputIterator>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
void insert(_InputIterator __f, _InputIterator __l) void insert(_InputIterator __f, _InputIterator __l)

View File

@ -909,7 +909,61 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
const_iterator cend() const _NOEXCEPT {return __table_.end();} const_iterator cend() const _NOEXCEPT {return __table_.end();}
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> insert(const value_type& __x)
{return __table_.__insert_unique(__x);}
iterator insert(const_iterator __p, const value_type& __x) {
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
"unordered_map::insert(const_iterator, const value_type&) called with an iterator not"
" referring to this unordered_map");
#endif
return insert(__x).first;
}
template <class _InputIterator>
void insert(_InputIterator __first, _InputIterator __last);
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
_LIBCPP_INLINE_VISIBILITY
void insert(initializer_list<value_type> __il)
{insert(__il.begin(), __il.end());}
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
#ifndef _LIBCPP_CXX03_LANG #ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> insert(value_type&& __x)
{return __table_.__insert_unique(_VSTD::move(__x));}
iterator insert(const_iterator __p, value_type&& __x) {
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
"unordered_map::insert(const_iterator, const value_type&) called with an iterator not"
" referring to this unordered_map");
#endif
return __table_.__insert_unique(_VSTD::move(__x)).first;
}
template <class _Pp,
class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> insert(_Pp&& __x)
{return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));}
template <class _Pp,
class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __p, _Pp&& __x)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
"unordered_map::insert(const_iterator, value_type&&) called with an iterator not"
" referring to this unordered_map");
#endif
return insert(_VSTD::forward<_Pp>(__x)).first;
}
template <class... _Args> template <class... _Args>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> emplace(_Args&&... __args) { pair<iterator, bool> emplace(_Args&&... __args) {
@ -927,55 +981,7 @@ public:
return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
} }
#endif // _LIBCPP_CXX03_LANG #endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> insert(const value_type& __x)
{return __table_.__insert_unique(__x);}
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _Pp,
class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
_LIBCPP_INLINE_VISIBILITY
pair<iterator, bool> insert(_Pp&& __x)
{return __table_.__insert_unique(_VSTD::forward<_Pp>(__x));}
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
#if _LIBCPP_DEBUG_LEVEL >= 2
iterator insert(const_iterator __p, const value_type& __x)
{
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
"unordered_map::insert(const_iterator, const value_type&) called with an iterator not"
" referring to this unordered_map");
return insert(__x).first;
}
#else
iterator insert(const_iterator, const value_type& __x)
{return insert(__x).first;}
#endif
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _Pp,
class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
_LIBCPP_INLINE_VISIBILITY
#if _LIBCPP_DEBUG_LEVEL >= 2
iterator insert(const_iterator __p, _Pp&& __x)
{
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
"unordered_map::insert(const_iterator, value_type&&) called with an iterator not"
" referring to this unordered_map");
return insert(_VSTD::forward<_Pp>(__x)).first;
}
#else
iterator insert(const_iterator, _Pp&& __x)
{return insert(_VSTD::forward<_Pp>(__x)).first;}
#endif
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _InputIterator>
void insert(_InputIterator __first, _InputIterator __last);
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
_LIBCPP_INLINE_VISIBILITY
void insert(initializer_list<value_type> __il)
{insert(__il.begin(), __il.end());}
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
#if _LIBCPP_STD_VER > 14 #if _LIBCPP_STD_VER > 14
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@ -1684,7 +1690,42 @@ public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
const_iterator cend() const _NOEXCEPT {return __table_.end();} const_iterator cend() const _NOEXCEPT {return __table_.end();}
_LIBCPP_INLINE_VISIBILITY
iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __p, const value_type& __x)
{return __table_.__insert_multi(__p.__i_, __x);}
template <class _InputIterator>
void insert(_InputIterator __first, _InputIterator __last);
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
_LIBCPP_INLINE_VISIBILITY
void insert(initializer_list<value_type> __il)
{insert(__il.begin(), __il.end());}
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
#ifndef _LIBCPP_CXX03_LANG #ifndef _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
iterator insert(value_type&& __x) {return __table_.__insert_multi(_VSTD::move(__x));}
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __p, value_type&& __x)
{return __table_.__insert_multi(__p.__i_, _VSTD::move(__x));}
template <class _Pp,
class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
_LIBCPP_INLINE_VISIBILITY
iterator insert(_Pp&& __x)
{return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));}
template <class _Pp,
class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __p, _Pp&& __x)
{return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));}
template <class... _Args> template <class... _Args>
iterator emplace(_Args&&... __args) { iterator emplace(_Args&&... __args) {
return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...); return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...);
@ -1696,32 +1737,6 @@ public:
} }
#endif // _LIBCPP_CXX03_LANG #endif // _LIBCPP_CXX03_LANG
_LIBCPP_INLINE_VISIBILITY
iterator insert(const value_type& __x) {return __table_.__insert_multi(__x);}
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _Pp,
class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
_LIBCPP_INLINE_VISIBILITY
iterator insert(_Pp&& __x)
{return __table_.__insert_multi(_VSTD::forward<_Pp>(__x));}
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __p, const value_type& __x)
{return __table_.__insert_multi(__p.__i_, __x);}
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _Pp,
class = typename enable_if<is_constructible<value_type, _Pp>::value>::type>
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __p, _Pp&& __x)
{return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));}
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _InputIterator>
void insert(_InputIterator __first, _InputIterator __last);
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
_LIBCPP_INLINE_VISIBILITY
void insert(initializer_list<value_type> __il)
{insert(__il.begin(), __il.end());}
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);} iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);}

View File

@ -25,6 +25,7 @@
int main() int main()
{ {
testMapInsert<TCT::map<> >(); testMapInsert<TCT::map<> >();
testMapInsertHint<TCT::map<> >();
testMapEmplace<TCT::map<> >(); testMapEmplace<TCT::map<> >();
testMapEmplaceHint<TCT::map<> >(); testMapEmplaceHint<TCT::map<> >();
} }

View File

@ -16,74 +16,57 @@
#include <map> #include <map>
#include <cassert> #include <cassert>
#include "test_macros.h"
#include "min_allocator.h" #include "min_allocator.h"
template <class Container>
void do_insert_cv_test()
{
typedef Container M;
typedef std::pair<typename M::iterator, bool> R;
typedef typename M::value_type VT;
M m;
const VT v1(2, 2.5);
R r = m.insert(v1);
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 1);
assert(r.first->first == 2);
assert(r.first->second == 2.5);
const VT v2(1, 1.5);
r = m.insert(v2);
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 2);
assert(r.first->first == 1);
assert(r.first->second == 1.5);
const VT v3(3, 3.5);
r = m.insert(v3);
assert(r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3.5);
const VT v4(3, 4.5);
r = m.insert(v4);
assert(!r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3.5);
}
int main() int main()
{ {
{ do_insert_cv_test<std::map<int, double> >();
typedef std::map<int, double> M; #if TEST_STD_VER >= 11
typedef std::pair<M::iterator, bool> R;
M m;
R r = m.insert(M::value_type(2, 2.5));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 1);
assert(r.first->first == 2);
assert(r.first->second == 2.5);
r = m.insert(M::value_type(1, 1.5));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 2);
assert(r.first->first == 1);
assert(r.first->second == 1.5);
r = m.insert(M::value_type(3, 3.5));
assert(r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3.5);
r = m.insert(M::value_type(3, 3.5));
assert(!r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3.5);
}
#if __cplusplus >= 201103L
{ {
typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
typedef std::pair<M::iterator, bool> R; do_insert_cv_test<M>();
M m;
R r = m.insert(M::value_type(2, 2.5));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 1);
assert(r.first->first == 2);
assert(r.first->second == 2.5);
r = m.insert(M::value_type(1, 1.5));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 2);
assert(r.first->first == 1);
assert(r.first->second == 1.5);
r = m.insert(M::value_type(3, 3.5));
assert(r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3.5);
r = m.insert(M::value_type(3, 3.5));
assert(!r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3.5);
} }
#endif #endif
} }

View File

@ -16,66 +16,53 @@
#include <map> #include <map>
#include <cassert> #include <cassert>
#include "test_macros.h"
#include "min_allocator.h" #include "min_allocator.h"
template <class Container>
void do_insert_iter_cv_test()
{
typedef Container M;
typedef typename M::iterator R;
typedef typename M::value_type VT;
M m;
const VT v1(2, 2.5);
R r = m.insert(m.end(), v1);
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2.5);
const VT v2(1, 1.5);
r = m.insert(m.end(), v2);
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1.5);
const VT v3(3, 3.5);
r = m.insert(m.end(), v3);
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
const VT v4(3, 4.5);
r = m.insert(m.end(), v4);
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
}
int main() int main()
{ {
{ do_insert_iter_cv_test<std::map<int, double> >();
typedef std::map<int, double> M; #if TEST_STD_VER >= 11
typedef M::iterator R;
M m;
R r = m.insert(m.end(), M::value_type(2, 2.5));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2.5);
r = m.insert(m.end(), M::value_type(1, 1.5));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1.5);
r = m.insert(m.end(), M::value_type(3, 3.5));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
r = m.insert(m.end(), M::value_type(3, 3.5));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
}
#if __cplusplus >= 201103L
{ {
typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::map<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
typedef M::iterator R; do_insert_iter_cv_test<M>();
M m;
R r = m.insert(m.end(), M::value_type(2, 2.5));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2.5);
r = m.insert(m.end(), M::value_type(1, 1.5));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1.5);
r = m.insert(m.end(), M::value_type(3, 3.5));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
r = m.insert(m.end(), M::value_type(3, 3.5));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
} }
#endif #endif
} }

View File

@ -7,6 +7,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <map> // <map>
// class map // class map
@ -21,70 +23,49 @@
#include "min_allocator.h" #include "min_allocator.h"
#include "test_macros.h" #include "test_macros.h"
template <class Container, class Pair>
void do_insert_iter_rv_test()
{
typedef Container M;
typedef Pair P;
typedef typename M::iterator R;
M m;
R r = m.insert(m.end(), P(2, 2));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2);
r = m.insert(m.end(), P(1, 1));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1);
r = m.insert(m.end(), P(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
r = m.insert(m.end(), P(3, 4));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
}
int main() int main()
{ {
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES do_insert_iter_rv_test<std::map<int, MoveOnly>, std::pair<int, MoveOnly>>();
{ do_insert_iter_rv_test<std::map<int, MoveOnly>, std::pair<const int, MoveOnly>>();
typedef std::map<int, MoveOnly> M;
typedef std::pair<int, MoveOnly> P;
typedef M::iterator R;
M m;
R r = m.insert(m.end(), P(2, 2));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2);
r = m.insert(m.end(), P(1, 1));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1);
r = m.insert(m.end(), P(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
r = m.insert(m.end(), P(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
}
#if TEST_STD_VER >= 11
{ {
typedef std::map<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M; typedef std::map<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M;
typedef std::pair<int, MoveOnly> P; typedef std::pair<int, MoveOnly> P;
typedef M::iterator R; typedef std::pair<const int, MoveOnly> CP;
M m; do_insert_iter_rv_test<M, P>();
R r = m.insert(m.end(), P(2, 2)); do_insert_iter_rv_test<M, CP>();
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2);
r = m.insert(m.end(), P(1, 1));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1);
r = m.insert(m.end(), P(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
r = m.insert(m.end(), P(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
} }
#endif
#if TEST_STD_VER > 14
{ {
typedef std::map<int, MoveOnly> M; typedef std::map<int, MoveOnly> M;
typedef M::iterator R; typedef M::iterator R;
@ -113,6 +94,5 @@ int main()
assert(r->first == 3); assert(r->first == 3);
assert(r->second == 3); assert(r->second == 3);
} }
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
#endif
} }

View File

@ -7,6 +7,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <map> // <map>
// class map // class map
@ -22,76 +24,54 @@
#include "min_allocator.h" #include "min_allocator.h"
#include "test_macros.h" #include "test_macros.h"
template <class Container, class Pair>
void do_insert_rv_test()
{
typedef Container M;
typedef Pair P;
typedef std::pair<typename M::iterator, bool> R;
M m;
R r = m.insert(P(2, 2));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 1);
assert(r.first->first == 2);
assert(r.first->second == 2);
r = m.insert(P(1, 1));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 2);
assert(r.first->first == 1);
assert(r.first->second == 1);
r = m.insert(P(3, 3));
assert(r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3);
r = m.insert(P(3, 3));
assert(!r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3);
}
int main() int main()
{ {
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES do_insert_rv_test<std::map<int, MoveOnly>, std::pair<int, MoveOnly>>();
{ do_insert_rv_test<std::map<int, MoveOnly>, std::pair<const int, MoveOnly>>();
typedef std::map<int, MoveOnly> M;
typedef std::pair<M::iterator, bool> R;
M m;
R r = m.insert(M::value_type(2, 2));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 1);
assert(r.first->first == 2);
assert(r.first->second == 2);
r = m.insert(M::value_type(1, 1));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 2);
assert(r.first->first == 1);
assert(r.first->second == 1);
r = m.insert(M::value_type(3, 3));
assert(r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3);
r = m.insert(M::value_type(3, 3));
assert(!r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3);
}
#if TEST_STD_VER >= 11
{ {
typedef std::map<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M; typedef std::map<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M;
typedef std::pair<M::iterator, bool> R; typedef std::pair<int, MoveOnly> P;
M m; typedef std::pair<const int, MoveOnly> CP;
R r = m.insert(M::value_type(2, 2)); do_insert_rv_test<M, P>();
assert(r.second); do_insert_rv_test<M, CP>();
assert(r.first == m.begin());
assert(m.size() == 1);
assert(r.first->first == 2);
assert(r.first->second == 2);
r = m.insert(M::value_type(1, 1));
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 2);
assert(r.first->first == 1);
assert(r.first->second == 1);
r = m.insert(M::value_type(3, 3));
assert(r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3);
r = m.insert(M::value_type(3, 3));
assert(!r.second);
assert(r.first == prev(m.end()));
assert(m.size() == 3);
assert(r.first->first == 3);
assert(r.first->second == 3);
} }
#endif
#if TEST_STD_VER > 14
{ {
typedef std::map<int, MoveOnly> M; typedef std::map<int, MoveOnly> M;
typedef std::pair<M::iterator, bool> R; typedef std::pair<M::iterator, bool> R;
@ -124,6 +104,4 @@ int main()
assert(r.first->first == 3); assert(r.first->first == 3);
assert(r.first->second == 3); assert(r.first->second == 3);
} }
#endif
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
} }

View File

@ -24,4 +24,5 @@
int main() int main()
{ {
testMultimapInsert<TCT::multimap<> >(); testMultimapInsert<TCT::multimap<> >();
testMultimapInsertHint<TCT::multimap<> >();
} }

View File

@ -16,66 +16,54 @@
#include <map> #include <map>
#include <cassert> #include <cassert>
#include "test_macros.h"
#include "min_allocator.h" #include "min_allocator.h"
template <class Container>
void do_insert_test() {
typedef Container M;
typedef typename M::iterator R;
typedef typename M::value_type VT;
M m;
const VT v1(2, 2.5);
R r = m.insert(v1);
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2.5);
const VT v2(1, 1.5);
r = m.insert(v2);
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1.5);
const VT v3(3, 3.5);
r = m.insert(v3);
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
const VT v4(3, 3.5);
r = m.insert(v4);
assert(r == prev(m.end()));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 3.5);
}
int main() int main()
{ {
{ {
typedef std::multimap<int, double> M; typedef std::multimap<int, double> Container;
typedef M::iterator R; do_insert_test<Container>();
M m;
R r = m.insert(M::value_type(2, 2.5));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2.5);
r = m.insert(M::value_type(1, 1.5));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1.5);
r = m.insert(M::value_type(3, 3.5));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
r = m.insert(M::value_type(3, 3.5));
assert(r == prev(m.end()));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 3.5);
} }
#if __cplusplus >= 201103L #if TEST_STD_VER >= 11
{ {
typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> Container;
typedef M::iterator R; do_insert_test<Container>();
M m;
R r = m.insert(M::value_type(2, 2.5));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2.5);
r = m.insert(M::value_type(1, 1.5));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1.5);
r = m.insert(M::value_type(3, 3.5));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
r = m.insert(M::value_type(3, 3.5));
assert(r == prev(m.end()));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 3.5);
} }
#endif #endif
} }

View File

@ -16,66 +16,52 @@
#include <map> #include <map>
#include <cassert> #include <cassert>
#include "test_macros.h"
#include "min_allocator.h" #include "min_allocator.h"
template <class Container>
void do_insert_hint_test()
{
typedef Container M;
typedef typename M::iterator R;
typedef typename M::value_type VT;
M m;
const VT v1(2, 2.5);
R r = m.insert(m.end(), v1);
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2.5);
const VT v2(1, 1.5);
r = m.insert(m.end(), v2);
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1.5);
const VT v3(3, 3.5);
r = m.insert(m.end(), v3);
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
const VT v4(3, 4.5);
r = m.insert(prev(m.end()), v4);
assert(r == prev(m.end(), 2));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 4.5);
}
int main() int main()
{ {
{ do_insert_hint_test<std::multimap<int, double> >();
typedef std::multimap<int, double> M; #if TEST_STD_VER >= 11
typedef M::iterator R;
M m;
R r = m.insert(m.end(), M::value_type(2, 2.5));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2.5);
r = m.insert(m.end(), M::value_type(1, 1.5));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1.5);
r = m.insert(m.end(), M::value_type(3, 3.5));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
r = m.insert(prev(m.end()), M::value_type(3, 4.5));
assert(r == prev(m.end(), 2));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 4.5);
}
#if __cplusplus >= 201103L
{ {
typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M; typedef std::multimap<int, double, std::less<int>, min_allocator<std::pair<const int, double>>> M;
typedef M::iterator R; do_insert_hint_test<M>();
M m;
R r = m.insert(m.end(), M::value_type(2, 2.5));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2.5);
r = m.insert(m.end(), M::value_type(1, 1.5));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1.5);
r = m.insert(m.end(), M::value_type(3, 3.5));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3.5);
r = m.insert(prev(m.end()), M::value_type(3, 4.5));
assert(r == prev(m.end(), 2));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 4.5);
} }
#endif #endif
} }

View File

@ -7,6 +7,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <map> // <map>
// class multimap // class multimap
@ -21,73 +23,53 @@
#include "min_allocator.h" #include "min_allocator.h"
#include "test_macros.h" #include "test_macros.h"
template <class Container, class Pair>
void do_insert_rv_test()
{
typedef Container M;
typedef Pair P;
typedef typename M::iterator R;
M m;
R r = m.insert(m.cend(), P(2, 2));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2);
r = m.insert(m.cend(), P(1, 1));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1);
r = m.insert(m.cend(), P(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
r = m.insert(m.cend(), P(3, 2));
assert(r == prev(m.end()));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 2);
}
int main() int main()
{ {
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES do_insert_rv_test<std::multimap<int, MoveOnly>, std::pair<int, MoveOnly> >();
{ do_insert_rv_test<std::multimap<int, MoveOnly>, std::pair<const int, MoveOnly> >();
typedef std::multimap<int, MoveOnly> M;
typedef std::pair<int, MoveOnly> P;
typedef M::iterator R;
M m;
R r = m.insert(m.cend(), P(2, 2));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2);
r = m.insert(m.cend(), P(1, 1));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1);
r = m.insert(m.cend(), P(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
r = m.insert(m.cend(), P(3, 2));
assert(r == prev(m.end()));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 2);
}
#if TEST_STD_VER >= 11
{ {
typedef std::multimap<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M; typedef std::multimap<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M;
typedef std::pair<int, MoveOnly> P; typedef std::pair<int, MoveOnly> P;
typedef M::iterator R; typedef std::pair<const int, MoveOnly> CP;
M m; do_insert_rv_test<M, P>();
R r = m.insert(m.cend(), P(2, 2)); do_insert_rv_test<M, CP>();
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2);
r = m.insert(m.cend(), P(1, 1));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1);
r = m.insert(m.cend(), P(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
r = m.insert(m.cend(), P(3, 2));
assert(r == prev(m.end()));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 2);
} }
#endif
#if TEST_STD_VER > 14
{ {
typedef std::multimap<int, MoveOnly> M; typedef std::multimap<int, MoveOnly> M;
typedef std::pair<int, MoveOnly> P;
typedef M::iterator R; typedef M::iterator R;
M m; M m;
R r = m.insert(m.cend(), {2, MoveOnly(2)}); R r = m.insert(m.cend(), {2, MoveOnly(2)});
@ -114,6 +96,4 @@ int main()
assert(r->first == 3); assert(r->first == 3);
assert(r->second == 2); assert(r->second == 2);
} }
#endif
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
} }

View File

@ -7,6 +7,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <map> // <map>
// class multimap // class multimap
@ -21,68 +23,45 @@
#include "min_allocator.h" #include "min_allocator.h"
#include "test_macros.h" #include "test_macros.h"
template <class Container>
void do_insert_rv_test()
{
typedef std::multimap<int, MoveOnly> M;
typedef typename M::iterator R;
typedef typename M::value_type VT;
M m;
R r = m.insert(VT(2, 2));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2);
r = m.insert(VT(1, 1));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1);
r = m.insert(VT(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
r = m.insert(VT(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 3);
}
int main() int main()
{ {
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES do_insert_rv_test<std::multimap<int, MoveOnly>>();
{
typedef std::multimap<int, MoveOnly> M;
typedef M::iterator R;
M m;
R r = m.insert(M::value_type(2, 2));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2);
r = m.insert(M::value_type(1, 1));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1);
r = m.insert(M::value_type(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
r = m.insert(M::value_type(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 3);
}
#if TEST_STD_VER >= 11
{ {
typedef std::multimap<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M; typedef std::multimap<int, MoveOnly, std::less<int>, min_allocator<std::pair<const int, MoveOnly>>> M;
typedef M::iterator R; do_insert_rv_test<M>();
M m;
R r = m.insert(M::value_type(2, 2));
assert(r == m.begin());
assert(m.size() == 1);
assert(r->first == 2);
assert(r->second == 2);
r = m.insert(M::value_type(1, 1));
assert(r == m.begin());
assert(m.size() == 2);
assert(r->first == 1);
assert(r->second == 1);
r = m.insert(M::value_type(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 3);
assert(r->first == 3);
assert(r->second == 3);
r = m.insert(M::value_type(3, 3));
assert(r == prev(m.end()));
assert(m.size() == 4);
assert(r->first == 3);
assert(r->second == 3);
} }
#endif
#if TEST_STD_VER > 14
{ {
typedef std::multimap<int, MoveOnly> M; typedef std::multimap<int, MoveOnly> M;
typedef M::iterator R; typedef M::iterator R;
@ -111,6 +90,4 @@ int main()
assert(r->first == 3); assert(r->first == 3);
assert(r->second == 3); assert(r->second == 3);
} }
#endif
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
} }

View File

@ -33,6 +33,8 @@ template <class Container>
void testMapInsert() void testMapInsert()
{ {
typedef typename Container::value_type ValueTp; typedef typename Container::value_type ValueTp;
typedef typename Container::key_type Key;
typedef typename Container::mapped_type Mapped;
typedef Container C; typedef Container C;
typedef std::pair<typename C::iterator, bool> R; typedef std::pair<typename C::iterator, bool> R;
ConstructController* cc = getConstructController(); ConstructController* cc = getConstructController();
@ -89,6 +91,18 @@ void testMapInsert()
assert(c.insert(std::move(v2)).second == false); assert(c.insert(std::move(v2)).second == false);
} }
} }
{
CHECKPOINT("Testing C::insert({key, value})");
Container c;
cc->expect<ValueTp&&>();
assert(c.insert({42, 1}).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>)"); CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)");
Container c; Container c;
@ -142,6 +156,140 @@ void testMapInsert()
} }
} }
template <class Container>
void testMapInsertHint()
{
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::insert(p, const value_type&)");
Container c;
const ValueTp v(42, 1);
cc->expect<const ValueTp&>();
It ret = c.insert(c.end(), v);
assert(ret != c.end());
assert(c.size() == 1);
assert(!cc->unchecked());
{
DisableAllocationGuard g;
const ValueTp v2(42, 1);
It ret2 = c.insert(c.begin(), v2);
assert(&(*ret2) == &(*ret));
assert(c.size() == 1);
}
}
{
CHECKPOINT("Testing C::insert(p, value_type&)");
Container c;
ValueTp v(42, 1);
cc->expect<ValueTp const&>();
It ret = c.insert(c.end(), v);
assert(ret != c.end());
assert(c.size() == 1);
assert(!cc->unchecked());
{
DisableAllocationGuard g;
ValueTp v2(42, 1);
It ret2 = c.insert(c.begin(), v2);
assert(&(*ret2) == &(*ret));
assert(c.size() == 1);
}
}
{
CHECKPOINT("Testing C::insert(p, value_type&&)");
Container c;
ValueTp v(42, 1);
cc->expect<ValueTp&&>();
It ret = c.insert(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.insert(c.begin(), std::move(v2));
assert(&(*ret2) == &(*ret));
assert(c.size() == 1);
}
}
{
CHECKPOINT("Testing C::insert(p, {key, value})");
Container c;
cc->expect<ValueTp&&>();
It ret = c.insert(c.end(), {42, 1});
assert(ret != c.end());
assert(c.size() == 1);
assert(!cc->unchecked());
{
DisableAllocationGuard g;
It ret2 = c.insert(c.begin(), {42, 1});
assert(&(*ret2) == &(*ret));
assert(c.size() == 1);
}
}
{
CHECKPOINT("Testing C::insert(p, const value_type&&)");
Container c;
const ValueTp v(42, 1);
cc->expect<const ValueTp&>();
It ret = c.insert(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.insert(c.begin(), std::move(v2));
assert(&(*ret2) == &(*ret));
assert(c.size() == 1);
}
}
{
CHECKPOINT("Testing C::insert(p, pair<Key, Mapped> const&)");
Container c;
const NonConstKeyPair v(42, 1);
cc->expect<const NonConstKeyPair&>();
It ret = c.insert(c.end(), v);
assert(ret != c.end());
assert(c.size() == 1);
assert(!cc->unchecked());
{
DisableAllocationGuard g;
const NonConstKeyPair v2(42, 1);
It ret2 = c.insert(c.begin(), v2);
assert(&(*ret2) == &(*ret));
assert(c.size() == 1);
}
}
{
CHECKPOINT("Testing C::insert(p, pair<Key, Mapped>&&)");
Container c;
NonConstKeyPair v(42, 1);
cc->expect<NonConstKeyPair&&>();
It ret = c.insert(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.insert(c.begin(), std::move(v2));
assert(&(*ret2) == &(*ret));
assert(c.size() == 1);
}
}
}
template <class Container> template <class Container>
void testMapEmplace() void testMapEmplace()
{ {
@ -509,6 +657,13 @@ void testMultimapInsert()
c.insert(std::move(v)); c.insert(std::move(v));
assert(!cc->unchecked()); assert(!cc->unchecked());
} }
{
CHECKPOINT("Testing C::insert({key, value})");
Container c;
cc->expect<ValueTp&&>();
c.insert({42, 1});
assert(!cc->unchecked());
}
{ {
CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)"); CHECKPOINT("Testing C::insert(std::initializer_list<ValueTp>)");
Container c; Container c;
@ -542,7 +697,47 @@ void testMultimapInsert()
c.insert(std::begin(ValueList), std::end(ValueList)); c.insert(std::begin(ValueList), std::end(ValueList));
assert(!cc->unchecked()); assert(!cc->unchecked());
} }
}
template <class Container>
void testMultimapInsertHint()
{
typedef typename Container::value_type ValueTp;
typedef Container C;
ConstructController* cc = getConstructController();
cc->reset();
{
CHECKPOINT("Testing C::insert(p, const value_type&)");
Container c;
const ValueTp v(42, 1);
cc->expect<const ValueTp&>();
c.insert(c.begin(), v);
assert(!cc->unchecked());
}
{
CHECKPOINT("Testing C::insert(p, value_type&)");
Container c;
ValueTp v(42, 1);
cc->expect<ValueTp&>();
c.insert(c.begin(), v);
assert(!cc->unchecked());
}
{
CHECKPOINT("Testing C::insert(p, value_type&&)");
Container c;
ValueTp v(42, 1);
cc->expect<ValueTp&&>();
c.insert(c.begin(), std::move(v));
assert(!cc->unchecked());
}
{
CHECKPOINT("Testing C::insert(p, {key, value})");
Container c;
cc->expect<ValueTp&&>();
c.insert(c.begin(), {42, 1});
assert(!cc->unchecked());
}
} }
#endif #endif

View File

@ -25,6 +25,7 @@
int main() int main()
{ {
testMapInsert<TCT::unordered_map<> >(); testMapInsert<TCT::unordered_map<> >();
testMapInsertHint<TCT::unordered_map<> >();
testMapEmplace<TCT::unordered_map<> >(); testMapEmplace<TCT::unordered_map<> >();
testMapEmplaceHint<TCT::unordered_map<> >(); testMapEmplaceHint<TCT::unordered_map<> >();
} }

View File

@ -18,69 +18,64 @@
#include <unordered_map> #include <unordered_map>
#include <cassert> #include <cassert>
#include "test_macros.h"
#include "min_allocator.h" #include "min_allocator.h"
template <class Container>
void do_insert_cv_test()
{
typedef Container M;
typedef std::pair<typename M::iterator, bool> R;
typedef typename M::value_type VT;
M m;
const VT v1(2.5, 2);
R r = m.insert(v1);
assert(r.second);
assert(m.size() == 1);
assert(r.first->first == 2.5);
assert(r.first->second == 2);
r = m.insert(VT(2.5, 3)); // test rvalue insertion works in C++03
assert(!r.second);
assert(m.size() == 1);
assert(r.first->first == 2.5);
assert(r.first->second == 2);
const VT v2(1.5, 1);
r = m.insert(v2);
assert(r.second);
assert(m.size() == 2);
assert(r.first->first == 1.5);
assert(r.first->second == 1);
const VT v3(3.5, 3);
r = m.insert(v3);
assert(r.second);
assert(m.size() == 3);
assert(r.first->first == 3.5);
assert(r.first->second == 3);
const VT v4(3.5, 4);
r = m.insert(v4);
assert(!r.second);
assert(m.size() == 3);
assert(r.first->first == 3.5);
assert(r.first->second == 3);
}
int main() int main()
{ {
{ {
typedef std::unordered_map<double, int> C; typedef std::unordered_map<double, int> M;
typedef std::pair<C::iterator, bool> R; do_insert_cv_test<M>();
typedef C::value_type P;
C c;
R r = c.insert(P(3.5, 3));
assert(r.second);
assert(c.size() == 1);
assert(r.first->first == 3.5);
assert(r.first->second == 3);
r = c.insert(P(3.5, 4));
assert(!r.second);
assert(c.size() == 1);
assert(r.first->first == 3.5);
assert(r.first->second == 3);
r = c.insert(P(4.5, 4));
assert(r.second);
assert(c.size() == 2);
assert(r.first->first == 4.5);
assert(r.first->second == 4);
r = c.insert(P(5.5, 4));
assert(r.second);
assert(c.size() == 3);
assert(r.first->first == 5.5);
assert(r.first->second == 4);
} }
#if __cplusplus >= 201103L #if TEST_STD_VER >= 11
{ {
typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>, typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>,
min_allocator<std::pair<const double, int>>> C; min_allocator<std::pair<const double, int>>> M;
typedef std::pair<C::iterator, bool> R; do_insert_cv_test<M>();
typedef C::value_type P;
C c;
R r = c.insert(P(3.5, 3));
assert(r.second);
assert(c.size() == 1);
assert(r.first->first == 3.5);
assert(r.first->second == 3);
r = c.insert(P(3.5, 4));
assert(!r.second);
assert(c.size() == 1);
assert(r.first->first == 3.5);
assert(r.first->second == 3);
r = c.insert(P(4.5, 4));
assert(r.second);
assert(c.size() == 2);
assert(r.first->first == 4.5);
assert(r.first->second == 4);
r = c.insert(P(5.5, 4));
assert(r.second);
assert(c.size() == 3);
assert(r.first->first == 5.5);
assert(r.first->second == 4);
} }
#endif #endif
} }

View File

@ -7,6 +7,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <unordered_map> // <unordered_map>
// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
@ -55,7 +57,6 @@ int main()
assert(r->first == 5.5); assert(r->first == 5.5);
assert(r->second == 4); assert(r->second == 4);
} }
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{ {
typedef std::unordered_map<MoveOnly, MoveOnly> C; typedef std::unordered_map<MoveOnly, MoveOnly> C;
typedef C::iterator R; typedef C::iterator R;
@ -82,8 +83,6 @@ int main()
assert(r->first == 5); assert(r->first == 5);
assert(r->second == 4); assert(r->second == 4);
} }
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
#if __cplusplus >= 201103L
{ {
typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>, typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>,
min_allocator<std::pair<const double, int>>> C; min_allocator<std::pair<const double, int>>> C;
@ -111,7 +110,6 @@ int main()
assert(r->first == 5.5); assert(r->first == 5.5);
assert(r->second == 4); assert(r->second == 4);
} }
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{ {
typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>,
min_allocator<std::pair<const MoveOnly, MoveOnly>>> C; min_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
@ -139,7 +137,31 @@ int main()
assert(r->first == 5); assert(r->first == 5);
assert(r->second == 4); assert(r->second == 4);
} }
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES {
typedef std::unordered_map<double, MoveOnly> C;
typedef C::iterator R;
C c;
C::const_iterator e = c.end();
R r = c.insert(e, {3.5, 3});
assert(c.size() == 1);
assert(r->first == 3.5);
assert(r->second == 3);
r = c.insert(c.end(), {3.5, 4});
assert(c.size() == 1);
assert(r->first == 3.5);
assert(r->second == 3);
r = c.insert(c.end(), {4.5, 4});
assert(c.size() == 2);
assert(r->first == 4.5);
assert(r->second == 4);
r = c.insert(c.end(), {5.5, 4});
assert(c.size() == 3);
assert(r->first == 5.5);
assert(r->second == 4);
}
#if _LIBCPP_DEBUG >= 1 #if _LIBCPP_DEBUG >= 1
{ {
typedef std::unordered_map<double, int> C; typedef std::unordered_map<double, int> C;
@ -152,5 +174,4 @@ int main()
assert(false); assert(false);
} }
#endif #endif
#endif
} }

View File

@ -7,6 +7,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <unordered_map> // <unordered_map>
// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
@ -54,7 +56,6 @@ int main()
assert(r.first->first == 5.5); assert(r.first->first == 5.5);
assert(r.first->second == 4); assert(r.first->second == 4);
} }
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{ {
typedef std::unordered_map<MoveOnly, MoveOnly> C; typedef std::unordered_map<MoveOnly, MoveOnly> C;
typedef std::pair<C::iterator, bool> R; typedef std::pair<C::iterator, bool> R;
@ -84,8 +85,6 @@ int main()
assert(r.first->first == 5); assert(r.first->first == 5);
assert(r.first->second == 4); assert(r.first->second == 4);
} }
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
#if __cplusplus >= 201103L
{ {
typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>, typedef std::unordered_map<double, int, std::hash<double>, std::equal_to<double>,
min_allocator<std::pair<const double, int>>> C; min_allocator<std::pair<const double, int>>> C;
@ -116,7 +115,6 @@ int main()
assert(r.first->first == 5.5); assert(r.first->first == 5.5);
assert(r.first->second == 4); assert(r.first->second == 4);
} }
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{ {
typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>,
min_allocator<std::pair<const MoveOnly, MoveOnly>>> C; min_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
@ -147,6 +145,32 @@ int main()
assert(r.first->first == 5); assert(r.first->first == 5);
assert(r.first->second == 4); assert(r.first->second == 4);
} }
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES {
#endif typedef std::unordered_map<double, MoveOnly> C;
typedef std::pair<C::iterator, bool> R;
C c;
R r = c.insert({3.5, 3});
assert(r.second);
assert(c.size() == 1);
assert(r.first->first == 3.5);
assert(r.first->second == 3);
r = c.insert({3.5, 4});
assert(!r.second);
assert(c.size() == 1);
assert(r.first->first == 3.5);
assert(r.first->second == 3);
r = c.insert({4.5, 4});
assert(r.second);
assert(c.size() == 2);
assert(r.first->first == 4.5);
assert(r.first->second == 4);
r = c.insert({5.5, 4});
assert(r.second);
assert(c.size() == 3);
assert(r.first->first == 5.5);
assert(r.first->second == 4);
}
} }

View File

@ -23,4 +23,5 @@
int main() int main()
{ {
testMultimapInsert<TCT::unordered_multimap<> >(); testMultimapInsert<TCT::unordered_multimap<> >();
testMultimapInsertHint<TCT::unordered_multimap<> >();
} }

View File

@ -7,6 +7,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <unordered_map> // <unordered_map>
// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
@ -55,7 +57,6 @@ int main()
assert(r->first == 5.5); assert(r->first == 5.5);
assert(r->second == 4); assert(r->second == 4);
} }
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{ {
typedef std::unordered_multimap<MoveOnly, MoveOnly> C; typedef std::unordered_multimap<MoveOnly, MoveOnly> C;
typedef C::iterator R; typedef C::iterator R;
@ -82,8 +83,6 @@ int main()
assert(r->first == 5); assert(r->first == 5);
assert(r->second == 4); assert(r->second == 4);
} }
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
#if __cplusplus >= 201103L
{ {
typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>, typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>,
min_allocator<std::pair<const double, int>>> C; min_allocator<std::pair<const double, int>>> C;
@ -111,7 +110,6 @@ int main()
assert(r->first == 5.5); assert(r->first == 5.5);
assert(r->second == 4); assert(r->second == 4);
} }
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{ {
typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>,
min_allocator<std::pair<const MoveOnly, MoveOnly>>> C; min_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
@ -139,7 +137,31 @@ int main()
assert(r->first == 5); assert(r->first == 5);
assert(r->second == 4); assert(r->second == 4);
} }
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES {
typedef std::unordered_multimap<double, int> C;
typedef C::iterator R;
C c;
C::const_iterator e = c.end();
R r = c.insert(e, {3.5, 3});
assert(c.size() == 1);
assert(r->first == 3.5);
assert(r->second == 3);
r = c.insert(r, {3.5, 4});
assert(c.size() == 2);
assert(r->first == 3.5);
assert(r->second == 4);
r = c.insert(c.end(), {4.5, 4});
assert(c.size() == 3);
assert(r->first == 4.5);
assert(r->second == 4);
r = c.insert(c.end(), {5.5, 4});
assert(c.size() == 4);
assert(r->first == 5.5);
assert(r->second == 4);
}
#if _LIBCPP_DEBUG >= 1 #if _LIBCPP_DEBUG >= 1
{ {
typedef std::unordered_multimap<double, int> C; typedef std::unordered_multimap<double, int> C;
@ -152,5 +174,4 @@ int main()
assert(false); assert(false);
} }
#endif #endif
#endif
} }

View File

@ -7,6 +7,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// UNSUPPORTED: c++98, c++03
// <unordered_map> // <unordered_map>
// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
@ -50,7 +52,6 @@ int main()
assert(r->first == 5.5); assert(r->first == 5.5);
assert(r->second == 4); assert(r->second == 4);
} }
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{ {
typedef std::unordered_multimap<MoveOnly, MoveOnly> C; typedef std::unordered_multimap<MoveOnly, MoveOnly> C;
typedef C::iterator R; typedef C::iterator R;
@ -76,8 +77,6 @@ int main()
assert(r->first == 5); assert(r->first == 5);
assert(r->second == 4); assert(r->second == 4);
} }
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
#if __cplusplus >= 201103L
{ {
typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>, typedef std::unordered_multimap<double, int, std::hash<double>, std::equal_to<double>,
min_allocator<std::pair<const double, int>>> C; min_allocator<std::pair<const double, int>>> C;
@ -104,7 +103,6 @@ int main()
assert(r->first == 5.5); assert(r->first == 5.5);
assert(r->second == 4); assert(r->second == 4);
} }
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
{ {
typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>, typedef std::unordered_multimap<MoveOnly, MoveOnly, std::hash<MoveOnly>, std::equal_to<MoveOnly>,
min_allocator<std::pair<const MoveOnly, MoveOnly>>> C; min_allocator<std::pair<const MoveOnly, MoveOnly>>> C;
@ -131,6 +129,28 @@ int main()
assert(r->first == 5); assert(r->first == 5);
assert(r->second == 4); assert(r->second == 4);
} }
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES {
#endif typedef std::unordered_multimap<double, MoveOnly> C;
typedef C::iterator R;
C c;
R r = c.insert({3.5, 3});
assert(c.size() == 1);
assert(r->first == 3.5);
assert(r->second == 3);
r = c.insert({3.5, 4});
assert(c.size() == 2);
assert(r->first == 3.5);
assert(r->second == 4);
r = c.insert({4.5, 4});
assert(c.size() == 3);
assert(r->first == 4.5);
assert(r->second == 4);
r = c.insert({5.5, 4});
assert(c.size() == 4);
assert(r->first == 5.5);
assert(r->second == 4);
}
} }

View File

@ -105,7 +105,7 @@
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2170">2170</a></td><td>Aggregates cannot be <code>DefaultConstructible</code></td><td>Urbana</td><td>Complete</td></tr> <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2170">2170</a></td><td>Aggregates cannot be <code>DefaultConstructible</code></td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2308">2308</td><td>Clarify container destructor requirements w.r.t. <code>std::array</code></td><td>Urbana</td><td>Complete</td></tr> <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2308">2308</td><td>Clarify container destructor requirements w.r.t. <code>std::array</code></td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2340">2340</a></td><td>Replacement allocation functions declared as inline</td><td>Urbana</td><td>Complete</td></tr> <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2340">2340</a></td><td>Replacement allocation functions declared as inline</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2354">2354</a></td><td>Unnecessary copying when inserting into maps with braced-init syntax</td><td>Urbana</td><td></td></tr> <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2354">2354</a></td><td>Unnecessary copying when inserting into maps with braced-init syntax</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2377">2377</a></td><td><code>std::align</code> requirements overly strict</td><td>Urbana</td><td>Complete</td></tr> <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2377">2377</a></td><td><code>std::align</code> requirements overly strict</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2396">2396</a></td><td><code>underlying_type</code> doesn't say what to do for an incomplete enumeration type</td><td>Urbana</td><td>Complete</td></tr> <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2396">2396</a></td><td><code>underlying_type</code> doesn't say what to do for an incomplete enumeration type</td><td>Urbana</td><td>Complete</td></tr>
<tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2399">2399</a></td><td><code>shared_ptr</code>'s constructor from <code>unique_ptr</code> should be constrained</td><td>Urbana</td><td>Complete</td></tr> <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2399">2399</a></td><td><code>shared_ptr</code>'s constructor from <code>unique_ptr</code> should be constrained</td><td>Urbana</td><td>Complete</td></tr>