diff --git a/test/unordered/init_type_insert_tests.cpp b/test/unordered/init_type_insert_tests.cpp index e9920d38..04bd6c23 100644 --- a/test/unordered/init_type_insert_tests.cpp +++ b/test/unordered/init_type_insert_tests.cpp @@ -26,16 +26,43 @@ struct move_only } }; -namespace std{ +namespace std { -template <> struct hash -{ - std::size_t operator()(move_only const& mo) const noexcept + template <> struct hash { - return std::hash()(mo.x_); + std::size_t operator()(move_only const& mo) const noexcept + { + return std::hash()(mo.x_); + } + }; + +} // namespace std + +struct immovable +{ + int x_ = -1; + + immovable() = default; + immovable(int x) : x_{x} {} + immovable(immovable const&) = delete; + immovable(immovable&&) = delete; + + friend bool operator==(immovable const& lhs, immovable const& rhs) + { + return lhs.x_ == rhs.x_; } }; +namespace std { + + template <> struct hash + { + std::size_t operator()(immovable const& im) const noexcept + { + return std::hash()(im.x_); + } + }; + } // namespace std struct raii_tracker @@ -68,15 +95,15 @@ struct raii_tracker } }; -namespace std{ +namespace std { -template <> struct hash -{ - std::size_t operator()(raii_tracker const& rt) const noexcept + template <> struct hash { - return std::hash()(rt.x_); - } -}; + std::size_t operator()(raii_tracker const& rt) const noexcept + { + return std::hash()(rt.x_); + } + }; } // namespace std @@ -235,10 +262,167 @@ static void test_insert_hint_tracking() BOOST_TEST_EQ(raii_tracker::move_constructs, 7u + 2u * map.size()); } +static void test_immovable() +{ + int const v = 128; + + boost::unordered_node_map > map; + + using init_type = decltype(map)::init_type; + static_assert( + std::is_same::value, + ""); + + map.emplace(1, v); + map.emplace(2, v); + + BOOST_TEST_EQ(map.size(), 2u); + + map.rehash(1024); + BOOST_TEST_GE(map.bucket_count(), 1024u); +} + +static void test_insert_node_tracking() +{ + raii_tracker::reset_counts(); + + BOOST_TEST_EQ(raii_tracker::copy_constructs, 0u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 0u); + + boost::unordered_node_map > + map; + + { + std::pair value{1, 2}; + + map.insert(value); + + BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 0u); + } + + { + std::pair value{2, 3}; + + map.insert(std::move(value)); + + BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 2u); + } + + { + std::pair value{3, 4}; + + map.insert(value); + + BOOST_TEST_EQ(raii_tracker::copy_constructs, 4u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 2u); + } + + { + std::pair value{4, 5}; + + map.insert(std::move(value)); + + BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 3u); + } + + { + map.insert(std::make_pair(5, 6)); + BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 5u); + } + + { + map.insert({6, 7}); + BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 7u); + } + + BOOST_TEST_EQ(map.size(), 6u); + + map.rehash(1024); + BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 7u); +} + +static void test_insert_hint_node_tracking() +{ + raii_tracker::reset_counts(); + + BOOST_TEST_EQ(raii_tracker::copy_constructs, 0u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 0u); + + boost::unordered_node_map > + map; + + { + std::pair value{1, 2}; + + map.insert(map.begin(), value); + + BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 0u); + } + + { + std::pair value{2, 3}; + + map.insert(std::move(value)); + + BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 2u); + } + + { + std::pair value{3, 4}; + + map.insert(map.begin(), value); + + BOOST_TEST_EQ(raii_tracker::copy_constructs, 4u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 2u); + } + + { + std::pair value{4, 5}; + + map.insert(map.begin(), std::move(value)); + + BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 3u); + } + + { + map.insert(map.begin(), std::make_pair(5, 6)); + BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 5u); + } + + { + map.insert(map.begin(), {6, 7}); + BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 7u); + } + + BOOST_TEST_EQ(map.size(), 6u); + + map.rehash(1024); + BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u); + BOOST_TEST_EQ(raii_tracker::move_constructs, 7u); +} + int main() { test_move_only(); test_insert_tracking(); test_insert_hint_tracking(); + + test_immovable(); + test_insert_node_tracking(); + test_insert_hint_node_tracking(); + return boost::report_errors(); }