I really don't like how the name and signature of the function changes between C++03 and C++11. It's confusing me a lot while reviewing the patch. I would much rather it always accept two parameters and be called __insert_unique_key_value.

We can add a C++03 __insert_unique_value that dispatches like you do above if needed.

Overall the dispatch looks good, but it could be a lot simpler. Instead of multi-level dispatch I would write a single trait to computer if "_Pp" is a keylike pair. Then insert(_Pp&&) just use that to call __insert_extract_key_if_referenceable directly using that trait.

I don't have any comments on this code at this time, but I want to caution people that this part of the standard library is extremely carefully specified, and meeting all the requirements is a fiddly bit of work.

For an example of this, look at LWG issue #2464, which has been added to the draft C++17 standard.

Nevertheless, I think this -- and the other over-eager allocations
in {unordered_,}{multi,}{map,set} -- are worth optimizing as long
as we can do it in a standards-compliant way. It's a pretty serious
regression in performance compared to expectations from C++03's
insert().

Let me know if you can think of some testing I can add to be sure
I'm not breaking anything (maybe test/std/.../ doesn't have enough
coverage?).

It took me a minute to understand why this doesn't break std::unordered_set<std::pair<T, U>>, could you make either the trait name, or implementation more explicit about the fact that it only ever returns true for "unordered_map"?

@dexonsmith Actually is it OK if I contribute the tests for this patch? Your's are in no way bad, but I want to test this in a similar manner to unord.map.modifiers/insert_allocator_requirments.pass.cpp and it's not fair to ask you to do that.

However if your willing to learn how to use support/container_test_types.h that even better :-)