LCOV - code coverage report
Current view: top level - utilities/test - unordered_set_test.cpp (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 89 93 95.7 %
Date: 2024-04-19 03:43:27 Functions: 25 26 96.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Maurice Laveaux
       2             : // Copyright: see the accompanying file COPYING or copy at
       3             : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0.
       6             : // (See accompanying file LICENSE_1_0.txt or copy at
       7             : // http://www.boost.org/LICENSE_1_0.txt)
       8             : //
       9             : 
      10             : 
      11             : #define BOOST_AUTO_TEST_MAIN
      12             : #include <boost/test/included/unit_test.hpp>
      13             : 
      14             : #include <random>
      15             : #include <unordered_set>
      16             : 
      17             : #include "mcrl2/utilities/hash_utility.h"
      18             : #include "mcrl2/utilities/unordered_map.h"
      19             : 
      20             : 
      21             : using namespace mcrl2::utilities;
      22             : 
      23             : template<typename T>
      24           6 : unordered_set<T> construct(std::initializer_list<T> list)
      25             : {
      26           6 :   unordered_set<T> set;
      27             : 
      28          30 :   for (const T& element : list)
      29             :   {
      30          24 :     set.emplace(element);
      31             :   }
      32             : 
      33           6 :   return set;
      34           0 : }
      35             : 
      36           2 : BOOST_AUTO_TEST_CASE(test_small)
      37             : {
      38             :   // Test with inserting 5, 3, 2, 5 expected { 2,3,5 }
      39           1 :   unordered_set<int> set = construct({5,3,2,5});
      40             : 
      41           1 :   BOOST_CHECK(set.find(5) != set.end());
      42           1 :   BOOST_CHECK(set.find(2) != set.end());
      43           1 :   BOOST_CHECK(set.find(3) != set.end());
      44             : 
      45           1 :   BOOST_CHECK(set.count(5) != 0);
      46           1 :   BOOST_CHECK(set.count(2) != 0);
      47           1 :   BOOST_CHECK(set.count(3) != 0);
      48             : 
      49           1 :   BOOST_CHECK(set.size() == 3);
      50           1 :   BOOST_CHECK(!set.empty());
      51           1 : }
      52             : 
      53           2 : BOOST_AUTO_TEST_CASE(test_large)
      54             : {
      55             :   // Test inserting a large number of elements (tests resize behaviour).
      56           1 :   std::random_device dev;
      57           1 :   std::mt19937 rng(dev());
      58           1 :   std::uniform_int_distribution<std::mt19937::result_type> dist(1,10000);
      59             : 
      60           1 :   unordered_set<int> test;
      61             : 
      62             :   // Here, we assume that the standard library implementation is correct.
      63           1 :   std::unordered_set<int> correct;
      64      100001 :   for (std::size_t i = 0; i < 100000; ++i)
      65             :   {
      66      100000 :     auto value = dist(rng);
      67      100000 :     test.emplace(value);
      68      100000 :     correct.emplace(value);
      69             :   }
      70             : 
      71             :   // Check that both contain the same elements.
      72       10000 :   for (auto& value : correct)
      73             :   {
      74        9999 :     BOOST_CHECK(test.find(value) != test.end());
      75             :   }
      76             : 
      77           1 :   BOOST_CHECK(test.size() == correct.size());
      78             : 
      79       10000 :   for (auto& value : test)
      80             :   {
      81        9999 :     BOOST_CHECK(correct.find(value) != correct.end());
      82             :   }
      83           1 : }
      84             : 
      85           2 : BOOST_AUTO_TEST_CASE(test_copy)
      86             : {
      87             :   // Test the copy constructor.
      88           1 :   unordered_set<int> set = construct({5,3,2,5});
      89             : 
      90           1 :   unordered_set<int> copy(set);
      91           1 :   set.clear();
      92             : 
      93           1 :   BOOST_CHECK(copy.find(5) != copy.end());
      94           1 :   BOOST_CHECK(copy.find(2) != copy.end());
      95           1 :   BOOST_CHECK(copy.find(3) != copy.end());
      96           1 : }
      97             : 
      98           2 : BOOST_AUTO_TEST_CASE(test_move)
      99             : {
     100             :   // Test the move constructor.
     101           1 :   unordered_set<int> set = construct({5,3,2,5});
     102           1 :   unordered_set<int> moved = std::move(set);
     103           1 : }
     104             : 
     105           2 : BOOST_AUTO_TEST_CASE(test_empty)
     106             : {
     107           1 :   unordered_set<int> set(0);
     108             : 
     109           1 :   BOOST_CHECK(set.empty());
     110           1 :   BOOST_CHECK(set.size() == 0);
     111             : 
     112           1 :   for (auto it = set.begin(); it != set.end(); ++it)
     113             :   {
     114           0 :     BOOST_CHECK(false);
     115             :   }
     116           1 : }
     117             : 
     118           2 : BOOST_AUTO_TEST_CASE(test_find_erase)
     119             : {
     120             :   // Try to erase an element using the iterator returned by find.
     121           1 :   unordered_set<int> set = construct({5,3,2,5});
     122             : 
     123           1 :   auto it = set.find(3);
     124           1 :   BOOST_CHECK(it != set.end());
     125           1 :   set.erase(it);
     126           1 : }
     127             : 
     128           2 : BOOST_AUTO_TEST_CASE(test_erase_begin)
     129             : {
     130             :   // Try to erase an element using the iterator returned by find.
     131           1 :   unordered_set<int> set = construct({5,3,2,5});
     132           1 :   set.erase(set.begin());
     133           1 : }
     134             : 
     135           2 : BOOST_AUTO_TEST_CASE(test_const_iterator)
     136             : {
     137           1 :   unordered_set<int> set = construct({5,3,2,5});
     138           1 :   auto it = set.begin();
     139           1 :   unordered_set<int>::const_iterator const_it = it;
     140             : 
     141           1 :   const unordered_set<int>::iterator it2 = set.begin();
     142           1 :   int value = *it2;
     143           1 :   BOOST_CHECK(value == *const_it);
     144           1 : }
     145             : 
     146             : class Object
     147             : {
     148             : public:
     149           2 :   Object(std::vector<int>&& reference)
     150           2 :     : m_vector(std::forward<std::vector<int>>(reference))
     151           2 :   {}
     152             : 
     153           0 :   bool operator==(const Object& other) const
     154             :   {
     155           0 :     return m_vector == other.m_vector;
     156             :   }
     157             : 
     158             : private:
     159             :   std::vector<int> m_vector;
     160             : };
     161             : 
     162             : namespace std
     163             : {
     164             : 
     165             : template<>
     166             : struct hash<Object>
     167             : {
     168           1 :   std::size_t operator()(const Object& object) const
     169             :   {
     170           1 :     return reinterpret_cast<std::size_t>(&object);
     171             :   }
     172             : };
     173             : 
     174             : }
     175             : 
     176           2 : BOOST_AUTO_TEST_CASE(test_perfect_forwarding)
     177             : {
     178           1 :   unordered_set<Object> objects;
     179             : 
     180             :   // Move it into the unordered_set.
     181           1 :   std::vector<int> test;
     182           1 :   objects.emplace(std::move(test));
     183           1 : }
     184             : 
     185           2 : BOOST_AUTO_TEST_CASE(test_try_emplace)
     186             : {
     187           1 :   unordered_map<int, std::vector<int>> mapping;
     188             : 
     189             :   // Move it into the unordered_set.
     190           1 :   std::vector<int> test;
     191           1 :   mapping.try_emplace(5, 1000);
     192             : 
     193           1 :   BOOST_CHECK(mapping.try_emplace(5, 1000).second == false);
     194           1 : }
     195             : 
     196           2 : BOOST_AUTO_TEST_CASE(test_emplace)
     197             : {
     198           1 :   unordered_map<int, std::vector<int>> mapping;
     199             : 
     200             :   // Move it into the unordered_set.
     201           1 :   mapping.emplace(5, 1000);
     202             : 
     203           1 :   BOOST_CHECK(mapping.emplace(5, 1000).second == false);
     204           1 : }

Generated by: LCOV version 1.14