diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-02-11 21:45:53 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-02-11 21:45:53 +0000 |
commit | 0f90567744f45174cc3abf0f07fc97563405f94d (patch) | |
tree | 07e1f0e57f34f20a7b81e8de459460dbd675d3ff /libcxx/test/std/containers | |
parent | 1cb8fac171fbd6bc8a65a677a47b5de391614e35 (diff) | |
download | bcm5719-llvm-0f90567744f45174cc3abf0f07fc97563405f94d.tar.gz bcm5719-llvm-0f90567744f45174cc3abf0f07fc97563405f94d.zip |
Fix LWG issue 2469 - Use piecewise construction in unordered_map::operator[].
unordered_map's allocator may only be used to construct objects of 'value_type',
or in this case 'pair<const Key, Value>'. In order to respect this requirement
in operator[], which requires default constructing the 'mapped_type', we have
to use pair's piecewise constructor with '(tuple<Kep>, tuple<>)'.
Unfortunately we still need to provide a fallback implementation for C++03
since we don't have <tuple>. Even worse this fallback is the last remaining
user of '__hash_map_node_destructor' and '__construct_node_with_key'.
llvm-svn: 260601
Diffstat (limited to 'libcxx/test/std/containers')
-rw-r--r-- | libcxx/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp | 55 | ||||
-rw-r--r-- | libcxx/test/std/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp | 9 |
2 files changed, 52 insertions, 12 deletions
diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp index c072248f866..4757c926f68 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.elem/index.pass.cpp @@ -19,8 +19,11 @@ #include <string> #include <cassert> +#include "test_macros.h" #include "MoveOnly.h" #include "min_allocator.h" +#include "count_new.hpp" +#include "container_test_types.h" int main() { @@ -44,7 +47,7 @@ int main() assert(c.size() == 5); assert(c.at(11) == "eleven"); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if TEST_STD_VER >= 11 { typedef std::unordered_map<MoveOnly, std::string> C; typedef std::pair<int, std::string> P; @@ -65,8 +68,6 @@ int main() assert(c.size() == 5); assert(c.at(11) == "eleven"); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES -#if __cplusplus >= 201103L { typedef std::unordered_map<int, std::string, std::hash<int>, std::equal_to<int>, min_allocator<std::pair<const int, std::string>>> C; @@ -88,7 +89,7 @@ int main() assert(c.size() == 5); assert(c.at(11) == "eleven"); } -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { typedef std::unordered_map<MoveOnly, std::string, std::hash<MoveOnly>, std::equal_to<MoveOnly>, min_allocator<std::pair<const MoveOnly, std::string>>> C; @@ -110,6 +111,50 @@ int main() assert(c.size() == 5); assert(c.at(11) == "eleven"); } -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + using Container = TCT::unordered_map<>; + using Key = Container::key_type; + using MappedType = Container::mapped_type; + using ValueTp = Container::value_type; + ConstructController* cc = getConstructController(); + cc->reset(); + { + Container c; + const Key k(1); + cc->expect<std::piecewise_construct_t const&, std::tuple<Key const&>&&, std::tuple<>&&>(); + MappedType& mref = c[k]; + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + MappedType& mref2 = c[k]; + assert(&mref == &mref2); + } + } + { + Container c; + Key k(1); + cc->expect<std::piecewise_construct_t const&, std::tuple<Key const&>&&, std::tuple<>&&>(); + MappedType& mref = c[k]; + assert(!cc->unchecked()); + { + DisableAllocationGuard g; + MappedType& mref2 = c[k]; + assert(&mref == &mref2); + } + } + { + Container c; + Key k(1); + cc->expect<std::piecewise_construct_t const&, std::tuple<Key &&>&&, std::tuple<>&&>(); + MappedType& mref = c[std::move(k)]; + assert(!cc->unchecked()); + { + Key k2(1); + DisableAllocationGuard g; + MappedType& mref2 = c[std::move(k2)]; + assert(&mref == &mref2); + } + } + } #endif } diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp index c319b5c30b2..f2c694e86f7 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.elem/index_tuple.pass.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +// UNSUPPORTED: c++98, c++03 + // <unordered_map> // template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, @@ -18,9 +20,6 @@ // http://llvm.org/bugs/show_bug.cgi?id=16542 #include <unordered_map> - -#ifndef _LIBCPP_HAS_NO_VARIADICS - #include <tuple> using namespace std; @@ -30,12 +29,8 @@ 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 } |