C++0x associative containers should have emplace() and emplace_hint() methods, but those in libstdc++ do not.
Yes, we lack *tons* of other C++0x things.
Reopening
I'm working on these, maybe will be ready in time for 4.6.0.
*** Bug 44872 has been marked as a duplicate of this bug. ***
Just to clarify a bit: this wasn't an *oversight*. We had the *nasty* problem in the Draft C++0x Standard with std::pair, which essentially made impossible adding the emplace_* members to std::map, std::multimap, etc, without breaking existing user code. Thus we waited on that, until things got clarified in this whole area. Now it's actually possible to work on those facilities. Anyway, much more generally: we are *not* claiming any sort of conformance to non existing (yet) standards, we are still in experimental mode for C++0x. Please be patient.
*** Bug 46148 has been marked as a duplicate of this bug. ***
And now we have n3178 too, great ;-/
First, I'm going to add the new insert overloads to the unordered containers.
taking 'iterator' params for consistency, or 'const_iterator' because we don't have to maintain compatibility?
I would say const_iterator, consistently with the existing insert and erase overloads...
doh, of course, we already use const_iterator in the unordered containers. sorry!
Author: paolo Date: Thu Oct 28 16:01:05 2010 New Revision: 166030 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=166030 Log: 2010-10-28 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/44436 (partial) * include/bits/hashtable.h (_Hashtable<>::insert(value_type&&), insert(_Pair&&), insert(const_iterator, value_type&&), insert(const_iterator, _Pair&&)): Add. (_M_allocate_node, _M_insert, _M_insert_bucket): Templatize. * include/bits/hashtable_policy.h (__detail::_Select1st): Add; use it throughout. (_Map_base<>::operator[](_Key&&)): Add. * include/bits/unordered_map.h: Use __detail::_Select1st throughout. * include/debug/unordered_map: Update. * include/debug/unordered_set: Likewise. * include/profile/unordered_map: Likewise. * include/profile/unordered_set: Likewise. * testsuite/util/testsuite_rvalref.h (struct hash<rvalstruct>): Add; minor tweaks throughout, use deleted special members. * testsuite/23_containers/unordered_map/insert/map_single_move-1.cc: New. * testsuite/23_containers/unordered_map/insert/map_single_move-2.cc: Likewise. * testsuite/23_containers/unordered_map/insert/array_syntax_move.cc: Likewise. * testsuite/23_containers/unordered_multimap/insert/ multimap_single_move-1.cc: Likewise. * testsuite/23_containers/unordered_multimap/insert/ multimap_single_move-2.cc: Likewise. * testsuite/23_containers/unordered_set/insert/set_single_move.cc: Likewise. * testsuite/23_containers/unordered_multiset/insert/ multiset_single_move.cc: Likewise. * testsuite/23_containers/unordered_map/insert/array_syntax.cc: Minor cosmetic changes. Added: trunk/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax_move.cc trunk/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_single_move-1.cc trunk/libstdc++-v3/testsuite/23_containers/unordered_map/insert/map_single_move-2.cc trunk/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_single_move-1.cc trunk/libstdc++-v3/testsuite/23_containers/unordered_multimap/insert/multimap_single_move-2.cc trunk/libstdc++-v3/testsuite/23_containers/unordered_multiset/insert/multiset_single_move.cc trunk/libstdc++-v3/testsuite/23_containers/unordered_set/insert/set_single_move.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/bits/hashtable.h trunk/libstdc++-v3/include/bits/hashtable_policy.h trunk/libstdc++-v3/include/bits/unordered_map.h trunk/libstdc++-v3/include/debug/unordered_map trunk/libstdc++-v3/include/debug/unordered_set trunk/libstdc++-v3/include/profile/unordered_map trunk/libstdc++-v3/include/profile/unordered_set trunk/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax.cc trunk/libstdc++-v3/testsuite/util/testsuite_rvalref.h
Author: paolo Date: Wed Nov 10 19:08:49 2010 New Revision: 166551 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=166551 Log: 2010-11-10 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/44436 (partial) PR libstdc++/46148 * include/bits/stl_tree.h (_Rb_tree<>::_M_insert_, _M_insert_lower, _M_insert_equal_lower, _M_insert_unique, _M_insert_equal, _M_insert_unique_, _M_insert_equal_): Templatize in C++0x mode, use _GLIBCXX_FORWARD throughout. * include/bits/stl_map.h (map<>::insert(_Pair&&), insert(const_iterator, _Pair&&), operator[](key_type&&): Add. * include/bits/stl_set.h (set<>::insert(value_type&&), insert(const_iterator, value_type&&)): Likewise. * include/bits/stl_multimap.h (multimap<>::insert(_Pair&&), insert(const_iterator, _Pair&&)): Likewise. * include/bits/stl_multiset.h (multiset<>::insert(value_type&&), insert(const_iterator, value_type&&)): Likewise. * include/debug/set.h: Adjust. * include/debug/multiset.h: Likewise. * include/debug/map.h: Likewise. * include/debug/multimap.h: Likewise. * include/profile/set.h: Likewise. * include/profile/multiset.h: Likewise. * include/profile/map.h: Likewise. * include/profile/multimap.h: Likewise. * testsuite/23_containers/multimap/modifiers/insert/1.cc: New. * testsuite/23_containers/multimap/modifiers/insert/2.cc: Likewise. * testsuite/23_containers/multimap/modifiers/insert/3.cc: Likewise. * testsuite/23_containers/multimap/modifiers/insert/4.cc: Likewise. * testsuite/23_containers/set/modifiers/insert/2.cc: Likewise. * testsuite/23_containers/set/modifiers/insert/3.cc: Likewise. * testsuite/23_containers/multiset/modifiers/insert/3.cc: Likewise. * testsuite/23_containers/multiset/modifiers/insert/4.cc: Likewise. * testsuite/23_containers/map/modifiers/insert/2.cc: Likewise. * testsuite/23_containers/map/modifiers/insert/3.cc: Likewise. * testsuite/23_containers/map/modifiers/insert/4.cc: Likewise. * testsuite/23_containers/map/modifiers/insert/5.cc: Likewise. * testsuite/23_containers/map/element_access/2.cc: Likewise. * testsuite/23_containers/map/element_access/46148.cc: Likewise. * include/bits/hashtable.h: Trivial naming changes. Added: trunk/libstdc++-v3/testsuite/23_containers/map/element_access/2.cc trunk/libstdc++-v3/testsuite/23_containers/map/element_access/46148.cc trunk/libstdc++-v3/testsuite/23_containers/map/modifiers/insert/2.cc trunk/libstdc++-v3/testsuite/23_containers/map/modifiers/insert/3.cc trunk/libstdc++-v3/testsuite/23_containers/map/modifiers/insert/4.cc trunk/libstdc++-v3/testsuite/23_containers/map/modifiers/insert/5.cc trunk/libstdc++-v3/testsuite/23_containers/multimap/modifiers/insert/1.cc trunk/libstdc++-v3/testsuite/23_containers/multimap/modifiers/insert/2.cc trunk/libstdc++-v3/testsuite/23_containers/multimap/modifiers/insert/3.cc trunk/libstdc++-v3/testsuite/23_containers/multimap/modifiers/insert/4.cc trunk/libstdc++-v3/testsuite/23_containers/multiset/modifiers/insert/3.cc trunk/libstdc++-v3/testsuite/23_containers/multiset/modifiers/insert/4.cc trunk/libstdc++-v3/testsuite/23_containers/set/modifiers/insert/2.cc trunk/libstdc++-v3/testsuite/23_containers/set/modifiers/insert/3.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/bits/hashtable.h trunk/libstdc++-v3/include/bits/stl_map.h trunk/libstdc++-v3/include/bits/stl_multimap.h trunk/libstdc++-v3/include/bits/stl_multiset.h trunk/libstdc++-v3/include/bits/stl_set.h trunk/libstdc++-v3/include/bits/stl_tree.h trunk/libstdc++-v3/include/debug/map.h trunk/libstdc++-v3/include/debug/multimap.h trunk/libstdc++-v3/include/debug/multiset.h trunk/libstdc++-v3/include/debug/set.h trunk/libstdc++-v3/include/profile/map.h trunk/libstdc++-v3/include/profile/multimap.h trunk/libstdc++-v3/include/profile/multiset.h trunk/libstdc++-v3/include/profile/set.h
The insert* are done.
Half a year since the last comment has passed but I still can't use emplace and this means I can't use unique_ptr in a map (or can I?). Is it really so hard to code emplace methods? Can we somehow help? rgds, Kira
I don't see what the emplace members have to do with unique_ptr. Anyway, I'm working on something else at the moment, contributions are always welcome, just file a Copyright Assignment and send over patches, thanks in advance!
Eg, this works perfectly well already, since I added the insert members: set<unique_ptr<int>> s; unique_ptr<int> up; s.insert(std::move(up));
(In reply to comment #15) > Is it really so hard to code emplace methods? Can we somehow help? It's not so hard, but we have limited resources and other priorities. Patches welcome, see http://gcc.gnu.org/onlinedocs/libstdc++/manual/appendix_contributing.html
Because the usual add functions would have to copy the unique_ptr and that doesn't work. As I see it in a map there are only insert functions for pairs. So if this works I'd have to create a pair and then use the created pair to insert it into the map, I'm gonna test it. But it would double the code size. As I understand it the emplace is just like an alias that forwards the 2 parameters into a pair constructor and inserts it afterwards. rgds, Kira
For sure the rationale behind emplace isn't inserting a pair of unique_ptrs in a map: maybe it can be a little more convenient in terms of lines of user code, but isn't the reason emplace exists.
Hi, I don't mean a pair of unique_ptr, just any combination with a unique_ptr. I for example very often need: std::map<uint32_t, unique_ptr<User>> instancesByIds_; Now if I want to insert a User, with a shared_ptr I'd have to do: instancesByIds_[id] = user; Now with a unique_ptr I'd like to do the same: instancesByIds_[id] = user; instancesByIds_[id] = std::move(user); Both doesnt work. Emplace is the practical solution (please correct me if there's a better way): instancesByIds_.emplace(id, std::move(user)); rgds, Kira
(In reply to comment #21) > Now with a unique_ptr I'd like to do the same: > > > instancesByIds_[id] = user; > instancesByIds_[id] = std::move(user); > > Both doesnt work. Nonsense. The second one works fine. This works too: instancesByIds_.insert(make_pair(id, std::move(user)));
(In reply to comment #22) > Nonsense. The second one works fine. Nope, it really doesn't! Or was this fixed in GCC 4.6.0 (I'm on 4.5.0 and this bug report is tagged to 4.5.0) Do you just claim this to work or did you actually test this? rgds, Kira
I tested it. It works. Just because the PR was reported against 4.5 doesn't mean it'll be fixed in that release series. Note there's no Target Milestone set for this PR. I can assure you the emplace member are not going to be added to GCC 4.5 so even when this is resolved you'll need to upgrade to use them. If you want to use the experimental C++0x support you really need to use an up-to-date release, complaining about lack of features in old releases is a waste of time, the 4.5 branch is only open for fixing regressions and updating documentation: http://gcc.gnu.org/ml/gcc/2011-04/msg00412.html
I'm sorry, don't misunderstand me, I'm willing to upgrade. I'm right now upgrading to 4.6 When I googled for this problem a year ago I've read that the second line doesn't work by *specification* and that you *have* to use emplace. I apologize for believing that crap (or maybe it was correct back then and the specification has been improved). Thanks for your help! :-) rgds, Kira
(In reply to comment #18) > (In reply to comment #15) > > Is it really so hard to code emplace methods? Can we somehow help? > > It's not so hard, but we have limited resources and other priorities. > > Patches welcome, see > http://gcc.gnu.org/onlinedocs/libstdc++/manual/appendix_contributing.html I started looking into it about a year ago, before you added insert(&&). It seems easy enough to add emplace for map, but what about set? For map, the first argument to emplace is going to be the key (I believe). We can therefore determine if the key is already present in the map before we construct the value object from the remaining arguments to emplace. For set, the key is the value, so I don't see a way to avoid constructing the value object from the arguments to emplace before you know if it should be inserted. Am I thinking about it the wrong way? BTW, I have been happily using insert(&&) for maps for at least 6 months (GCC built from trunk). I strongly suspect it is available with GCC 4.6. You definitely do not need emplace to store unique_ptr values in a map.
(In reply to comment #25) > When I googled for this problem a year ago I've read that the second line > doesn't work by *specification* and that you *have* to use emplace. No, that's never been true. The type of instancesByIds_[id] is a reference to the mapped_type, i.e. unique_ptr<User>& and you have always been able to move assign to a unique_ptr from an rvalue, by design. You would have to use emplace for a container of objects which were not copyable *or* movable, but unique_ptr is movable.
(In reply to comment #26) > For map, the first argument to emplace is going to be the key (I believe). We > can therefore determine if the key is already present in the map before we > construct the value object from the remaining arguments to emplace. Not necessarily: std::map<int, int> m; m.emplace(piecewise_construct_t, make_tuple(1), make_tuple(2));
Should the entry for 23.2.4 on the Library Status page (http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.200x) not say "Partial" until this is implemented?
Author: redi Date: Sun Nov 6 00:29:36 2011 New Revision: 181022 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=181022 Log: PR libstdc++/44436 * doc/xml/manual/status_cxx200x.xml: Document emplace members are missing. Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/doc/xml/manual/status_cxx200x.xml
Unordered containers done with this patch: 2011-12-09 François Dumont <fdumont@gcc.gnu.org> PR libstdc++/44436 (unordered containers emplace, emplace_hint bits) * include/bits/hashtable.h (_Hashtable<>::emplace, _Hashtable<>::emplace_hint): Add. ...
Author: fdumont Date: Mon Sep 24 19:53:36 2012 New Revision: 191679 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=191679 Log: 2012-09-24 François Dumont <fdumont@gcc.gnu.org> PR libstdc++/44436 * include/bits/stl_tree.h (_Rb_tree<>::_M_insert_): Take _Base_ptr rather than _Const_Base_ptr. (_Rb_tree<>::_M_insert_node): New. (_Rb_tree<>::_M_get_insert_unique_pos): New, search code of _M_insert_unique method. (_Rb_tree<>::_M_insert_unique): Use latter. (_Rb_tree<>::_M_emplace_unique): New, likewise. (_Rb_tree<>::_M_get_insert_equal_pos): New, search code of _M_insert_equal method. (_Rb_tree<>::_M_insert_equal): Use latter. (_Rb_tree<>::_M_emplace_equal): New, likewise. (_Rb_tree<>::_M_get_insert_hint_unique_pos): New, search code of _M_insert_unique_ method. (_Rb_tree<>::_M_insert_unique_): Use latter. (_Rb_tree<>::_M_emplace_hint_unique): New, likewise. (_Rb_tree<>::_M_get_insert_hint_equal_pos): New, search code of _M_insert_equal_ method. (_Rb_tree<>::_M_insert_equal_): Use latter. (_Rb_tree<>::_M_emplace_hint_equal): New, likewise. (_Rb_tree<>::_M_insert_lower): Remove first _Base_ptr parameter, useless as always null. * include/bits/stl_map.h: Include <tuple> in C++11. (map<>::operator[](const key_type&)): Use _Rb_tree<>::_M_emplace_hint_unique in C++11. (map<>::operator[](key_type&&)): Likewise. (map<>::emplace): New. (map<>::emplace_hint): New. * include/bits/stl_multimap.h (multimap<>::emplace): New. (multimap<>::emplace_hint): New. * include/bits/stl_set.h (set<>::emplace): New. (set<>::emplace_hint): New. * include/bits/stl_multiset.h (multiset<>::emplace): New. (multiset<>::emplace_hint): New. * include/debug/map.h (std::__debug::map<>::emplace): New. (std::__debug::map<>::emplace_hint): New. * include/debug/multimap.h (std::__debug::multimap<>::emplace): New. (std::__debug::multimap<>::emplace_hint): New. * include/debug/set.h (std::__debug::set<>::emplace): New. (std::__debug::set<>::emplace_hint): New. * include/debug/multiset.h (std::__debug::multiset<>::emplace): New. (std::__debug::multiset<>::emplace_hint): New. * include/profile/map.h (std::__profile::map<>::emplace): New. (std::__profile::map<>::emplace_hint): New. * include/profile/multimap.h (std::__profile::multimap<>::emplace): New. (std::__profile::multimap<>::emplace_hint): New. * include/profile/set.h (std::__profile::set<>::emplace): New. (std::__profile::set<>::emplace_hint): New. * include/profile/multiset.h (std::__profile::multiset<>::emplace): New. (std::__profile::multiset<>::emplace_hint): New. * testsuite/util/testsuite_container_traits.h: Signal that emplace and emplace_hint are available on std::map, std::multimap, std::set and std::multiset in C++11. * testsuite/23_containers/map/operators/2.cc: New. * testsuite/23_containers/map/modifiers/emplace/1.cc: New. * testsuite/23_containers/multimap/modifiers/emplace/1.cc: New. * testsuite/23_containers/set/modifiers/emplace/1.cc: New. * testsuite/23_containers/multiset/modifiers/emplace/1.cc: New. Added: trunk/libstdc++-v3/testsuite/23_containers/map/modifiers/emplace/ trunk/libstdc++-v3/testsuite/23_containers/map/modifiers/emplace/1.cc trunk/libstdc++-v3/testsuite/23_containers/map/operators/2.cc trunk/libstdc++-v3/testsuite/23_containers/multimap/modifiers/emplace/ trunk/libstdc++-v3/testsuite/23_containers/multimap/modifiers/emplace/1.cc trunk/libstdc++-v3/testsuite/23_containers/multiset/modifiers/emplace/ trunk/libstdc++-v3/testsuite/23_containers/multiset/modifiers/emplace/1.cc trunk/libstdc++-v3/testsuite/23_containers/set/modifiers/emplace/ trunk/libstdc++-v3/testsuite/23_containers/set/modifiers/emplace/1.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/bits/stl_map.h trunk/libstdc++-v3/include/bits/stl_multimap.h trunk/libstdc++-v3/include/bits/stl_multiset.h trunk/libstdc++-v3/include/bits/stl_set.h trunk/libstdc++-v3/include/bits/stl_tree.h trunk/libstdc++-v3/include/debug/map.h trunk/libstdc++-v3/include/debug/multimap.h trunk/libstdc++-v3/include/debug/multiset.h trunk/libstdc++-v3/include/debug/set.h trunk/libstdc++-v3/include/profile/map.h trunk/libstdc++-v3/include/profile/multimap.h trunk/libstdc++-v3/include/profile/multiset.h trunk/libstdc++-v3/include/profile/set.h trunk/libstdc++-v3/testsuite/util/testsuite_container_traits.h
Author: paolo Date: Tue Sep 25 08:43:38 2012 New Revision: 191695 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=191695 Log: 2012-09-25 Paolo Carlini <paolo.carlini@oracle.com> * doc/xml/manual/status_cxx2011.xml: Update vs PR 44436. Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
Finally done.