Removed extension in [unordered_][multi]map which allowed one to emplace using just an argument for the key, as opposed to using piecewise_construct. However a bug report exposed that this created an unfortunate ambiguity. People who are currently using the extension will be notified the next time they compile, and will have to change to using piecewise_construct. There are no ABI issues with the removal of this extension. This fixes http://llvm.org/bugs/show_bug.cgi?id=16542

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@185666 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Howard Hinnant
2013-07-04 20:59:16 +00:00
parent e008d4eecc
commit b66e1c3f96
12 changed files with 179 additions and 174 deletions

View File

@@ -0,0 +1,33 @@
//===----------------------------------------------------------------------===//
//
// 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
// mapped_type& operator[](const key_type& k);
// http://llvm.org/bugs/show_bug.cgi?id=16542
#include <map>
#ifndef _LIBCPP_HAS_NO_VARIADICS
#include <tuple>
#endif
int main()
{
#ifndef _LIBCPP_HAS_NO_VARIADICS
using namespace std;
map<tuple<int,int>, size_t> m;
m[make_tuple(2,3)]=7;
#endif
}

View File

@@ -37,14 +37,16 @@ int main()
assert(m.begin()->first == 0);
assert(m.begin()->second == DefaultOnly());
assert(DefaultOnly::count == 1);
r = m.emplace(1);
r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r.second);
assert(r.first == next(m.begin()));
assert(m.size() == 2);
assert(next(m.begin())->first == 1);
assert(next(m.begin())->second == DefaultOnly());
assert(DefaultOnly::count == 2);
r = m.emplace(1);
r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
std::forward_as_tuple());
assert(!r.second);
assert(r.first == next(m.begin()));
assert(m.size() == 2);
@@ -57,7 +59,8 @@ int main()
typedef std::map<int, Emplaceable> M;
typedef std::pair<M::iterator, bool> R;
M m;
R r = m.emplace(2);
R r = m.emplace(std::piecewise_construct, std::forward_as_tuple(2),
std::forward_as_tuple());
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 1);
@@ -102,14 +105,16 @@ int main()
assert(m.begin()->first == 0);
assert(m.begin()->second == DefaultOnly());
assert(DefaultOnly::count == 1);
r = m.emplace(1);
r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r.second);
assert(r.first == next(m.begin()));
assert(m.size() == 2);
assert(next(m.begin())->first == 1);
assert(next(m.begin())->second == DefaultOnly());
assert(DefaultOnly::count == 2);
r = m.emplace(1);
r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
std::forward_as_tuple());
assert(!r.second);
assert(r.first == next(m.begin()));
assert(m.size() == 2);
@@ -122,7 +127,8 @@ int main()
typedef std::map<int, Emplaceable, std::less<int>, min_allocator<std::pair<const int, Emplaceable>>> M;
typedef std::pair<M::iterator, bool> R;
M m;
R r = m.emplace(2);
R r = m.emplace(std::piecewise_construct, std::forward_as_tuple(2),
std::forward_as_tuple());
assert(r.second);
assert(r.first == m.begin());
assert(m.size() == 1);

View File

@@ -35,13 +35,17 @@ int main()
assert(m.begin()->first == 0);
assert(m.begin()->second == DefaultOnly());
assert(DefaultOnly::count == 1);
r = m.emplace_hint(m.end(), 1);
r = m.emplace_hint(m.end(), std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin()));
assert(m.size() == 2);
assert(next(m.begin())->first == 1);
assert(next(m.begin())->second == DefaultOnly());
assert(DefaultOnly::count == 2);
r = m.emplace_hint(m.end(), 1);
r = m.emplace_hint(m.end(), std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin()));
assert(m.size() == 2);
assert(next(m.begin())->first == 1);
@@ -53,7 +57,9 @@ int main()
typedef std::map<int, Emplaceable> M;
typedef M::iterator R;
M m;
R r = m.emplace_hint(m.end(), 2);
R r = m.emplace_hint(m.end(), std::piecewise_construct,
std::forward_as_tuple(2),
std::forward_as_tuple());
assert(r == m.begin());
assert(m.size() == 1);
assert(m.begin()->first == 2);
@@ -95,13 +101,17 @@ int main()
assert(m.begin()->first == 0);
assert(m.begin()->second == DefaultOnly());
assert(DefaultOnly::count == 1);
r = m.emplace_hint(m.end(), 1);
r = m.emplace_hint(m.end(), std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin()));
assert(m.size() == 2);
assert(next(m.begin())->first == 1);
assert(next(m.begin())->second == DefaultOnly());
assert(DefaultOnly::count == 2);
r = m.emplace_hint(m.end(), 1);
r = m.emplace_hint(m.end(), std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin()));
assert(m.size() == 2);
assert(next(m.begin())->first == 1);
@@ -113,7 +123,9 @@ int main()
typedef std::map<int, Emplaceable, std::less<int>, min_allocator<std::pair<const int, Emplaceable>>> M;
typedef M::iterator R;
M m;
R r = m.emplace_hint(m.end(), 2);
R r = m.emplace_hint(m.end(), std::piecewise_construct,
std::forward_as_tuple(2),
std::forward_as_tuple());
assert(r == m.begin());
assert(m.size() == 1);
assert(m.begin()->first == 2);

View File

@@ -35,13 +35,15 @@ int main()
assert(m.begin()->first == 0);
assert(m.begin()->second == DefaultOnly());
assert(DefaultOnly::count == 1);
r = m.emplace(1);
r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin()));
assert(m.size() == 2);
assert(next(m.begin())->first == 1);
assert(next(m.begin())->second == DefaultOnly());
assert(DefaultOnly::count == 2);
r = m.emplace(1);
r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin(), 2));
assert(m.size() == 3);
assert(next(m.begin(), 2)->first == 1);
@@ -53,7 +55,8 @@ int main()
typedef std::multimap<int, Emplaceable> M;
typedef M::iterator R;
M m;
R r = m.emplace(2);
R r = m.emplace(std::piecewise_construct, std::forward_as_tuple(2),
std::forward_as_tuple());
assert(r == m.begin());
assert(m.size() == 1);
assert(m.begin()->first == 2);
@@ -93,13 +96,15 @@ int main()
assert(m.begin()->first == 0);
assert(m.begin()->second == DefaultOnly());
assert(DefaultOnly::count == 1);
r = m.emplace(1);
r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin()));
assert(m.size() == 2);
assert(next(m.begin())->first == 1);
assert(next(m.begin())->second == DefaultOnly());
assert(DefaultOnly::count == 2);
r = m.emplace(1);
r = m.emplace(std::piecewise_construct, std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin(), 2));
assert(m.size() == 3);
assert(next(m.begin(), 2)->first == 1);
@@ -111,7 +116,8 @@ int main()
typedef std::multimap<int, Emplaceable, std::less<int>, min_allocator<std::pair<const int, Emplaceable>>> M;
typedef M::iterator R;
M m;
R r = m.emplace(2);
R r = m.emplace(std::piecewise_construct, std::forward_as_tuple(2),
std::forward_as_tuple());
assert(r == m.begin());
assert(m.size() == 1);
assert(m.begin()->first == 2);

View File

@@ -35,13 +35,17 @@ int main()
assert(m.begin()->first == 0);
assert(m.begin()->second == DefaultOnly());
assert(DefaultOnly::count == 1);
r = m.emplace_hint(m.cend(), 1);
r = m.emplace_hint(m.cend(), std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin()));
assert(m.size() == 2);
assert(next(m.begin())->first == 1);
assert(next(m.begin())->second == DefaultOnly());
assert(DefaultOnly::count == 2);
r = m.emplace_hint(m.cend(), 1);
r = m.emplace_hint(m.cend(), std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin(), 2));
assert(m.size() == 3);
assert(next(m.begin(), 2)->first == 1);
@@ -53,7 +57,9 @@ int main()
typedef std::multimap<int, Emplaceable> M;
typedef M::iterator R;
M m;
R r = m.emplace_hint(m.cend(), 2);
R r = m.emplace_hint(m.cend(), std::piecewise_construct,
std::forward_as_tuple(2),
std::forward_as_tuple());
assert(r == m.begin());
assert(m.size() == 1);
assert(m.begin()->first == 2);
@@ -95,13 +101,17 @@ int main()
assert(m.begin()->first == 0);
assert(m.begin()->second == DefaultOnly());
assert(DefaultOnly::count == 1);
r = m.emplace_hint(m.cend(), 1);
r = m.emplace_hint(m.cend(), std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin()));
assert(m.size() == 2);
assert(next(m.begin())->first == 1);
assert(next(m.begin())->second == DefaultOnly());
assert(DefaultOnly::count == 2);
r = m.emplace_hint(m.cend(), 1);
r = m.emplace_hint(m.cend(), std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple());
assert(r == next(m.begin(), 2));
assert(m.size() == 3);
assert(next(m.begin(), 2)->first == 1);
@@ -113,7 +123,9 @@ int main()
typedef std::multimap<int, Emplaceable, std::less<int>, min_allocator<std::pair<const int, Emplaceable>>> M;
typedef M::iterator R;
M m;
R r = m.emplace_hint(m.cend(), 2);
R r = m.emplace_hint(m.cend(), std::piecewise_construct,
std::forward_as_tuple(2),
std::forward_as_tuple());
assert(r == m.begin());
assert(m.size() == 1);
assert(m.begin()->first == 2);

View File

@@ -0,0 +1,41 @@
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//
// <unordered_map>
// template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
// class Alloc = allocator<pair<const Key, T>>>
// class unordered_map
// mapped_type& operator[](const key_type& k);
// http://llvm.org/bugs/show_bug.cgi?id=16542
#include <unordered_map>
#ifndef _LIBCPP_HAS_NO_VARIADICS
#include <tuple>
using namespace std;
struct my_hash
{
size_t operator()(const tuple<int,int>&) const {return 0;}
};
#endif
int main()
{
#ifndef _LIBCPP_HAS_NO_VARIADICS
unordered_map<tuple<int,int>, size_t, my_hash> m;
m[make_tuple(2,3)]=7;
#endif
}

View File

@@ -29,7 +29,8 @@ int main()
typedef std::unordered_map<int, Emplaceable> C;
typedef std::pair<C::iterator, bool> R;
C c;
R r = c.emplace(3);
R r = c.emplace(std::piecewise_construct, std::forward_as_tuple(3),
std::forward_as_tuple());
assert(r.second);
assert(c.size() == 1);
assert(r.first->first == 3);
@@ -54,7 +55,8 @@ int main()
min_allocator<std::pair<const int, Emplaceable>>> C;
typedef std::pair<C::iterator, bool> R;
C c;
R r = c.emplace(3);
R r = c.emplace(std::piecewise_construct, std::forward_as_tuple(3),
std::forward_as_tuple());
assert(r.second);
assert(c.size() == 1);
assert(r.first->first == 3);

View File

@@ -30,7 +30,8 @@ int main()
typedef C::iterator R;
C c;
C::const_iterator e = c.end();
R r = c.emplace_hint(e, 3);
R r = c.emplace_hint(e, std::piecewise_construct, std::forward_as_tuple(3),
std::forward_as_tuple());
assert(c.size() == 1);
assert(r->first == 3);
assert(r->second == Emplaceable());
@@ -53,7 +54,8 @@ int main()
typedef C::iterator R;
C c;
C::const_iterator e = c.end();
R r = c.emplace_hint(e, 3);
R r = c.emplace_hint(e, std::piecewise_construct, std::forward_as_tuple(3),
std::forward_as_tuple());
assert(c.size() == 1);
assert(r->first == 3);
assert(r->second == Emplaceable());

View File

@@ -29,7 +29,8 @@ int main()
typedef std::unordered_multimap<int, Emplaceable> C;
typedef C::iterator R;
C c;
R r = c.emplace(3);
R r = c.emplace(std::piecewise_construct, std::forward_as_tuple(3),
std::forward_as_tuple());
assert(c.size() == 1);
assert(r->first == 3);
assert(r->second == Emplaceable());
@@ -51,7 +52,8 @@ int main()
min_allocator<std::pair<const int, Emplaceable>>> C;
typedef C::iterator R;
C c;
R r = c.emplace(3);
R r = c.emplace(std::piecewise_construct, std::forward_as_tuple(3),
std::forward_as_tuple());
assert(c.size() == 1);
assert(r->first == 3);
assert(r->second == Emplaceable());

View File

@@ -30,7 +30,8 @@ int main()
typedef C::iterator R;
C c;
C::const_iterator e = c.end();
R r = c.emplace_hint(e, 3);
R r = c.emplace_hint(e, std::piecewise_construct, std::forward_as_tuple(3),
std::forward_as_tuple());
assert(c.size() == 1);
assert(r->first == 3);
assert(r->second == Emplaceable());
@@ -61,7 +62,8 @@ int main()
typedef C::iterator R;
C c;
C::const_iterator e = c.end();
R r = c.emplace_hint(e, 3);
R r = c.emplace_hint(e, std::piecewise_construct, std::forward_as_tuple(3),
std::forward_as_tuple());
assert(c.size() == 1);
assert(r->first == 3);
assert(r->second == Emplaceable());