From b4d62e46706c95ad1c869093e915cff81fe701c3 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Thu, 24 Oct 2013 18:11:35 +0000 Subject: [PATCH] Attempt to work around Visual C++ initializer list overload bug. I'm hoping that these templated initializer lists will be considered a better overload than the others. I have no idea if it will actually work, this is a real shot in the dark. The enable_if checks should probably be for implicit conversion, there might be a chance this could override a valid call when there's an explicit conversion. [SVN r86419] --- include/boost/unordered/unordered_map.hpp | 24 ++++++++++++++ include/boost/unordered/unordered_set.hpp | 24 ++++++++++++++ test/unordered/insert_tests.cpp | 39 +++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/include/boost/unordered/unordered_map.hpp b/include/boost/unordered/unordered_map.hpp index 7eecfbbb..ff35e345 100644 --- a/include/boost/unordered/unordered_map.hpp +++ b/include/boost/unordered/unordered_map.hpp @@ -22,6 +22,10 @@ #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800)) +#include +#endif #endif #if defined(BOOST_MSVC) @@ -403,6 +407,16 @@ namespace unordered #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) void insert(std::initializer_list); + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800)) + template + typename boost::enable_if_c< + boost::is_convertible::value, + void>::type insert(std::initializer_list list) + { + table_.insert_range(list.begin(), list.end()); + } +#endif #endif iterator erase(const_iterator); @@ -887,6 +901,16 @@ namespace unordered #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) void insert(std::initializer_list); + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800)) + template + typename boost::enable_if_c< + boost::is_convertible::value, + void>::type insert(std::initializer_list list) + { + table_.insert_range(list.begin(), list.end()); + } +#endif #endif iterator erase(const_iterator); diff --git a/include/boost/unordered/unordered_set.hpp b/include/boost/unordered/unordered_set.hpp index 73134bfe..03c7983c 100644 --- a/include/boost/unordered/unordered_set.hpp +++ b/include/boost/unordered/unordered_set.hpp @@ -22,6 +22,10 @@ #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #include + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800)) +#include +#endif #endif #if defined(BOOST_MSVC) @@ -402,6 +406,16 @@ namespace unordered #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) void insert(std::initializer_list); + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800)) + template + typename boost::enable_if_c< + boost::is_convertible::value, + void>::type insert(std::initializer_list list) + { + table_.insert_range(list.begin(), list.end()); + } +#endif #endif iterator erase(const_iterator); @@ -872,6 +886,16 @@ namespace unordered #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) void insert(std::initializer_list); + +#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800)) + template + typename boost::enable_if_c< + boost::is_convertible::value, + void>::type insert(std::initializer_list list) + { + table_.insert_range(list.begin(), list.end()); + } +#endif #endif iterator erase(const_iterator); diff --git a/test/unordered/insert_tests.cpp b/test/unordered/insert_tests.cpp index 66469ba3..e7a15e11 100644 --- a/test/unordered/insert_tests.cpp +++ b/test/unordered/insert_tests.cpp @@ -576,6 +576,21 @@ UNORDERED_TEST(map_insert_range_test2, #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +struct initialize_from_two_ints +{ + int a, b; + + friend std::size_t hash_value(initialize_from_two_ints const& x) + { + return a + b; + } + + bool operator==(initialize_from_two_ints const& x) + { + return a == x.a && b == x.b; + } +}; + UNORDERED_AUTO_TEST(insert_initializer_list_set) { boost::unordered_set set; @@ -583,6 +598,30 @@ UNORDERED_AUTO_TEST(insert_initializer_list_set) BOOST_TEST_EQ(set.size(), 3u); BOOST_TEST(set.find(1) != set.end()); BOOST_TEST(set.find(4) == set.end()); + + boost::unordered_set set2; + + set2.insert({1, 2}); + BOOST_TEST(set2.size() == 1); + BOOST_TEST(set2.find({1,2}) != set2.end()); + BOOST_TEST(set2.find({2,1}) != set2.end()); + + set2.insert({{3,4},{5,6},{7,8}}); + BOOST_TEST(set2.size() == 4); + BOOST_TEST(set2.find({1,2}) != set2.end()); + BOOST_TEST(set2.find({3,4}) != set2.end()); + BOOST_TEST(set2.find({5,6}) != set2.end()); + BOOST_TEST(set2.find({7,8}) != set2.end()); + BOOST_TEST(set2.find({8,7}) != set2.end()); + + set2.insert({{2, 1}, {3,4}}); + BOOST_TEST(set2.size() == 5); + BOOST_TEST(set2.find({1,2}) != set2.end()); + BOOST_TEST(set2.find({2,1}) != set2.end()); + BOOST_TEST(set2.find({3,4}) != set2.end()); + BOOST_TEST(set2.find({5,6}) != set2.end()); + BOOST_TEST(set2.find({7,8}) != set2.end()); + BOOST_TEST(set2.find({8,7}) != set2.end()); } UNORDERED_AUTO_TEST(insert_initializer_list_multiset)