#include "asl/containers/hash_set.hpp" #include "asl/testing/testing.hpp" #include "asl/tests/types.hpp" #include "asl/strings/string.hpp" #include "asl/strings/string_view.hpp" ASL_TEST(empty) { asl::hash_set set; ASL_TEST_EXPECT(set.size() == 0); for (int i = 0; i < 100; ++i) { ASL_TEST_EXPECT(!set.contains(i)); } } ASL_TEST(a_bunch_of_strings) { asl::hash_set> set; set.insert("Hello, world!"); ASL_TEST_EXPECT(set.size() == 1); set.insert("Hello, puppy!"); ASL_TEST_EXPECT(set.size() == 2); set.insert("Hello, puppy!"); ASL_TEST_EXPECT(set.size() == 2); ASL_TEST_EXPECT(set.contains("Hello, world!"_sv)); ASL_TEST_EXPECT(set.contains("Hello, puppy!"_sv)); ASL_TEST_EXPECT(!set.contains("Hello, Steven!"_sv)); } ASL_TEST(a_bunch_of_ints) { asl::hash_set set; int count = 3000; for (int i = 0; i < count; ++i) { set.insert(i); } ASL_TEST_EXPECT(set.size() == count); for (int i = 0; i < count * 2; ++i) { ASL_TEST_EXPECT(set.contains(i) == (i < count)); } } struct HashWithDestructor: public DestructorObserver { int x; HashWithDestructor(int x_, bool* ptr) : DestructorObserver{ptr} , x{x_} {} constexpr bool operator==(const HashWithDestructor& other) const { return x == other.x; } }; struct CustomComparator { static bool eq(const HashWithDestructor& a, const HashWithDestructor& b) { return a.x == b.x; } static bool eq(const HashWithDestructor& a, int b) { return a.x == b; } }; struct CustomHasher { static uint64_t hash(const HashWithDestructor& b) { return asl::hash_value(b.x); } static uint64_t hash(int x) { return asl::hash_value(x); } }; ASL_TEST(destructor_and_remove) { static constexpr int kCount = 200; bool destroyed[kCount]{}; { asl::hash_set set; for (int i = 0; i < kCount; ++i) { set.insert(i, &destroyed[i]); // NOLINT } ASL_TEST_EXPECT(set.size() == kCount); for (int i = 0; i < kCount; ++i) { ASL_TEST_EXPECT(!destroyed[i]); // NOLINT } for (int i = 0; i < kCount; i += 2) { ASL_TEST_EXPECT(set.remove(i)); } for (int i = 0; i < kCount; i += 2) { ASL_TEST_EXPECT(!set.contains(i)); ASL_TEST_EXPECT(set.contains(i+1)); ASL_TEST_EXPECT(destroyed[i]); // NOLINT ASL_TEST_EXPECT(!destroyed[i + 1]); // NOLINT } } for (int i = 0; i < kCount; ++i) { ASL_TEST_EXPECT(destroyed[i]); // NOLINT } } ASL_TEST(copy) { asl::hash_set set1; for (int i = 0; i < 100; ++i) { set1.insert(i); } asl::hash_set set2 = set1; asl::hash_set set3; set3 = set1; ASL_TEST_EXPECT(set2.size() == 100); ASL_TEST_EXPECT(set3.size() == 100); for (int i = 0; i < 100; ++i) { ASL_TEST_EXPECT(set2.contains(i)); ASL_TEST_EXPECT(set3.contains(i)); } } ASL_TEST(move) { asl::hash_set set1; for (int i = 0; i < 100; ++i) { set1.insert(i); } asl::hash_set set2 = ASL_MOVE(set1); ASL_TEST_EXPECT(set2.size() == 100); for (int i = 0; i < 100; ++i) { ASL_TEST_EXPECT(set2.contains(i)); } set1 = ASL_MOVE(set2); ASL_TEST_EXPECT(set1.size() == 100); for (int i = 0; i < 100; ++i) { ASL_TEST_EXPECT(set1.contains(i)); } }