unord: Extract key to avoid preemptive mallocs in insert/emplace
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Thu, 17 Mar 2016 20:45:20 +0000 (20:45 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Thu, 17 Mar 2016 20:45:20 +0000 (20:45 +0000)
commitfde79b40c21dc397a2524c728f4102260eceafed
treef343a80dd2321803035224644d14f4d2051746df
parent01a3cf4d31f3e7fa5a8ab4b4b7622900acda5340
unord: Extract key to avoid preemptive mallocs in insert/emplace

unordered_set::emplace and unordered_map::emplace construct a node, then
try to insert it.  If insertion fails, the node gets deleted.

To avoid this unnecessary malloc traffic, check to see if the argument
to emplace has the appropriate key_type.  If so, we can use that key
directly and delay the malloc until we're sure we're inserting something
new.

Test updates by Eric Fiselier, who rewrote the old allocation tests to
include the new cases.

There are two orthogonal future directions:

1. Apply the same optimization to set and map.

2. Extend the optimization to when the argument is not key_type, but can
   be converted to it without side effects.  Ideally, we could do this
   whenever key_type is trivially destructible and the argument is
   trivially convertible to key_type, but in practise the relevant type
   traits "blow up sometimes".  At least, we should catch a few simple
   cases (such as when both are primitive types).

llvm-svn: 263746
libcxx/include/__hash_table
libcxx/test/libcxx/containers/unord/unord.set/insert_dup_alloc.pass.cpp [deleted file]
libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/insert_and_emplace_allocator_requirements.pass.cpp [moved from libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/insert_allocator_requirements.pass.cpp with 58% similarity]
libcxx/test/std/containers/unord/unord.set/insert_and_emplace_allocator_requirements.pass.cpp [moved from libcxx/test/std/containers/unord/unord.set/insert_allocator_requirements.pass.cpp with 66% similarity]