blob: 34e4a6559ad121a6370d49f214d89378a031643c [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <unittest/unittest.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/intrusive_hash_table.h>
#include <fbl/tests/intrusive_containers/associative_container_test_environment.h>
#include <fbl/tests/intrusive_containers/intrusive_hash_table_checker.h>
#include <fbl/tests/intrusive_containers/test_thunks.h>
namespace fbl {
namespace tests {
namespace intrusive_containers {
using OtherKeyType = uint16_t;
using OtherHashType = uint32_t;
static constexpr OtherHashType kOtherNumBuckets = 23;
template <typename PtrType>
struct OtherHashTraits {
using ObjType = typename ::fbl::internal::ContainerPtrTraits<PtrType>::ValueType;
using BucketStateType = DoublyLinkedListNodeState<PtrType>;
// Linked List Traits
static BucketStateType& node_state(ObjType& obj) {
return obj.other_container_state_.bucket_state_;
}
// Keyed Object Traits
static OtherKeyType GetKey(const ObjType& obj) {
return obj.other_container_state_.key_;
}
static bool LessThan(const OtherKeyType& key1, const OtherKeyType& key2) {
return key1 < key2;
}
static bool EqualTo(const OtherKeyType& key1, const OtherKeyType& key2) {
return key1 == key2;
}
// Hash Traits
static OtherHashType GetHash(const OtherKeyType& key) {
return static_cast<OtherHashType>((key * 0xaee58187) % kOtherNumBuckets);
}
// Set key is a trait which is only used by the tests, not by the containers
// themselves.
static void SetKey(ObjType& obj, OtherKeyType key) {
obj.other_container_state_.key_ = key;
}
};
template <typename PtrType>
struct OtherHashState {
private:
friend struct OtherHashTraits<PtrType>;
OtherKeyType key_;
typename OtherHashTraits<PtrType>::BucketStateType bucket_state_;
};
template <typename PtrType>
class HTDLLTraits {
public:
using ObjType = typename ::fbl::internal::ContainerPtrTraits<PtrType>::ValueType;
using ContainerType = HashTable<size_t, PtrType, DoublyLinkedList<PtrType>>;
using ContainableBaseClass = DoublyLinkedListable<PtrType>;
using ContainerStateType = DoublyLinkedListNodeState<PtrType>;
using KeyType = typename ContainerType::KeyType;
using HashType = typename ContainerType::HashType;
using OtherContainerTraits = OtherHashTraits<PtrType>;
using OtherContainerStateType = OtherHashState<PtrType>;
using OtherBucketType = DoublyLinkedList<PtrType, OtherContainerTraits>;
using OtherContainerType = HashTable<OtherKeyType,
PtrType,
OtherBucketType,
OtherHashType,
kOtherNumBuckets,
OtherContainerTraits,
OtherContainerTraits>;
using TestObjBaseType = HashedTestObjBase<typename ContainerType::KeyType,
typename ContainerType::HashType,
ContainerType::kNumBuckets>;
};
DEFINE_TEST_OBJECTS(HTDLL);
using UMTE = DEFINE_TEST_THUNK(Associative, HTDLL, Unmanaged);
using UPTE = DEFINE_TEST_THUNK(Associative, HTDLL, UniquePtr);
using SUPDDTE = DEFINE_TEST_THUNK(Associative, HTDLL, StdUniquePtrDefaultDeleter);
using SUPCDTE = DEFINE_TEST_THUNK(Associative, HTDLL, StdUniquePtrCustomDeleter);
using RPTE = DEFINE_TEST_THUNK(Associative, HTDLL, RefPtr);
BEGIN_TEST_CASE(hashtable_dll_tests)
//////////////////////////////////////////
// General container specific tests.
//////////////////////////////////////////
RUN_NAMED_TEST("Clear (unmanaged)", UMTE::ClearTest)
RUN_NAMED_TEST("Clear (unique)", UPTE::ClearTest)
RUN_NAMED_TEST("Clear (std::uptr)", SUPDDTE::ClearTest)
RUN_NAMED_TEST("Clear (std::uptr<Del>)", SUPCDTE::ClearTest)
RUN_NAMED_TEST("Clear (RefPtr)", RPTE::ClearTest)
RUN_NAMED_TEST("ClearUnsafe (unmanaged)", UMTE::ClearUnsafeTest)
#if TEST_WILL_NOT_COMPILE || 0
RUN_NAMED_TEST("ClearUnsafe (unique)", UPTE::ClearUnsafeTest)
RUN_NAMED_TEST("ClearUnsafe (std::uptr)", SUPDDTE::ClearUnsafeTest)
RUN_NAMED_TEST("ClearUnsafe (std::uptr<Del>)", SUPCDTE::ClearUnsafeTest)
RUN_NAMED_TEST("ClearUnsafe (RefPtr)", RPTE::ClearUnsafeTest)
#endif
RUN_NAMED_TEST("IsEmpty (unmanaged)", UMTE::IsEmptyTest)
RUN_NAMED_TEST("IsEmpty (unique)", UPTE::IsEmptyTest)
RUN_NAMED_TEST("IsEmpty (std::uptr)", SUPDDTE::IsEmptyTest)
RUN_NAMED_TEST("IsEmpty (std::uptr<Del>)", SUPCDTE::IsEmptyTest)
RUN_NAMED_TEST("IsEmpty (RefPtr)", RPTE::IsEmptyTest)
RUN_NAMED_TEST("Iterate (unmanaged)", UMTE::IterateTest)
RUN_NAMED_TEST("Iterate (unique)", UPTE::IterateTest)
RUN_NAMED_TEST("Iterate (std::uptr)", SUPDDTE::IterateTest)
RUN_NAMED_TEST("Iterate (std::uptr<Del>)", SUPCDTE::IterateTest)
RUN_NAMED_TEST("Iterate (RefPtr)", RPTE::IterateTest)
RUN_NAMED_TEST("IterErase (unmanaged)", UMTE::IterEraseTest)
RUN_NAMED_TEST("IterErase (unique)", UPTE::IterEraseTest)
RUN_NAMED_TEST("IterErase (std::uptr)", SUPDDTE::IterEraseTest)
RUN_NAMED_TEST("IterErase (std::uptr<Del>)", SUPCDTE::IterEraseTest)
RUN_NAMED_TEST("IterErase (RefPtr)", RPTE::IterEraseTest)
RUN_NAMED_TEST("DirectErase (unmanaged)", UMTE::DirectEraseTest)
#if TEST_WILL_NOT_COMPILE || 0
RUN_NAMED_TEST("DirectErase (unique)", UPTE::DirectEraseTest)
RUN_NAMED_TEST("DirectErase (std::uptr)", SUPDDTE::DirectEraseTest)
RUN_NAMED_TEST("DirectErase (std::uptr<Del>)", SUPCDTE::DirectEraseTest)
#endif
RUN_NAMED_TEST("DirectErase (RefPtr)", RPTE::DirectEraseTest)
RUN_NAMED_TEST("MakeIterator (unmanaged)", UMTE::MakeIteratorTest)
#if TEST_WILL_NOT_COMPILE || 0
RUN_NAMED_TEST("MakeIterator (unique)", UPTE::MakeIteratorTest)
RUN_NAMED_TEST("MakeIterator (std::uptr)", SUPDDTE::MakeIteratorTest)
RUN_NAMED_TEST("MakeIterator (std::uptr<Del>)", SUPCDTE::MakeIteratorTest)
#endif
RUN_NAMED_TEST("MakeIterator (RefPtr)", RPTE::MakeIteratorTest)
RUN_NAMED_TEST("ReverseIterErase (unmanaged)", UMTE::ReverseIterEraseTest)
RUN_NAMED_TEST("ReverseIterErase (unique)", UPTE::ReverseIterEraseTest)
RUN_NAMED_TEST("ReverseIterErase (std::uptr)", SUPDDTE::ReverseIterEraseTest)
RUN_NAMED_TEST("ReverseIterErase (std::uptr<Del>)", SUPCDTE::ReverseIterEraseTest)
RUN_NAMED_TEST("ReverseIterErase (RefPtr)", RPTE::ReverseIterEraseTest)
RUN_NAMED_TEST("ReverseIterate (unmanaged)", UMTE::ReverseIterateTest)
RUN_NAMED_TEST("ReverseIterate (unique)", UPTE::ReverseIterateTest)
RUN_NAMED_TEST("ReverseIterate (std::uptr)", SUPDDTE::ReverseIterateTest)
RUN_NAMED_TEST("ReverseIterate (std::uptr<Del>)", SUPCDTE::ReverseIterateTest)
RUN_NAMED_TEST("ReverseIterate (RefPtr)", RPTE::ReverseIterateTest)
// Hash tables do not support swapping or Rvalue operations (Assignment or
// construction) as doing so would be an O(n) operation (With 'n' == to the
// number of buckets in the hashtable)
#if TEST_WILL_NOT_COMPILE || 0
RUN_NAMED_TEST("Swap (unmanaged)", UMTE::SwapTest)
RUN_NAMED_TEST("Swap (unique)", UPTE::SwapTest)
RUN_NAMED_TEST("Swap (std::uptr)", SUPDDTE::SwapTest)
RUN_NAMED_TEST("Swap (std::uptr<Del>)", SUPCDTE::SwapTest)
RUN_NAMED_TEST("Swap (RefPtr)", RPTE::SwapTest)
RUN_NAMED_TEST("Rvalue Ops (unmanaged)", UMTE::RvalueOpsTest)
RUN_NAMED_TEST("Rvalue Ops (unique)", UPTE::RvalueOpsTest)
RUN_NAMED_TEST("Rvalue Ops (std::uptr)", SUPDDTE::RvalueOpsTest)
RUN_NAMED_TEST("Rvalue Ops (std::uptr<Del>)", SUPCDTE::RvalueOpsTest)
RUN_NAMED_TEST("Rvalue Ops (RefPtr)", RPTE::RvalueOpsTest)
#endif
RUN_NAMED_TEST("Scope (unique)", UPTE::ScopeTest)
RUN_NAMED_TEST("Scope (std::uptr)", SUPDDTE::ScopeTest)
RUN_NAMED_TEST("Scope (std::uptr<Del>)", SUPCDTE::ScopeTest)
RUN_NAMED_TEST("Scope (RefPtr)", RPTE::ScopeTest)
RUN_NAMED_TEST("TwoContainer (unmanaged)", UMTE::TwoContainerTest)
#if TEST_WILL_NOT_COMPILE || 0
RUN_NAMED_TEST("TwoContainer (unique)", UPTE::TwoContainerTest)
RUN_NAMED_TEST("TwoContainer (std::uptr)", SUPDDTE::TwoContainerTest)
RUN_NAMED_TEST("TwoContainer (std::uptr<Del>)", SUPCDTE::TwoContainerTest)
#endif
RUN_NAMED_TEST("TwoContainer (RefPtr)", RPTE::TwoContainerTest)
RUN_NAMED_TEST("IterCopyPointer (unmanaged)", UMTE::IterCopyPointerTest)
#if TEST_WILL_NOT_COMPILE || 0
RUN_NAMED_TEST("IterCopyPointer (unique)", UPTE::IterCopyPointerTest)
RUN_NAMED_TEST("IterCopyPointer (std::uptr)", SUPDDTE::IterCopyPointerTest)
RUN_NAMED_TEST("IterCopyPointer (std::uptr<Del>)", SUPCDTE::IterCopyPointerTest)
#endif
RUN_NAMED_TEST("IterCopyPointer (RefPtr)", RPTE::IterCopyPointerTest)
RUN_NAMED_TEST("EraseIf (unmanaged)", UMTE::EraseIfTest)
RUN_NAMED_TEST("EraseIf (unique)", UPTE::EraseIfTest)
RUN_NAMED_TEST("EraseIf (std::uptr)", SUPDDTE::EraseIfTest)
RUN_NAMED_TEST("EraseIf (std::uptr<Del>)", SUPCDTE::EraseIfTest)
RUN_NAMED_TEST("EraseIf (RefPtr)", RPTE::EraseIfTest)
RUN_NAMED_TEST("FindIf (unmanaged)", UMTE::FindIfTest)
RUN_NAMED_TEST("FindIf (unique)", UPTE::FindIfTest)
RUN_NAMED_TEST("FindIf (std::uptr)", SUPDDTE::FindIfTest)
RUN_NAMED_TEST("FindIf (std::uptr<Del>)", SUPCDTE::FindIfTest)
RUN_NAMED_TEST("FindIf (RefPtr)", RPTE::FindIfTest)
//////////////////////////////////////////
// Associative container specific tests.
//////////////////////////////////////////
RUN_NAMED_TEST("InsertByKey (unmanaged)", UMTE::InsertByKeyTest)
RUN_NAMED_TEST("InsertByKey (unique)", UPTE::InsertByKeyTest)
RUN_NAMED_TEST("InsertByKey (std::uptr)", SUPDDTE::InsertByKeyTest)
RUN_NAMED_TEST("InsertByKey (std::uptr<Del>)", SUPCDTE::InsertByKeyTest)
RUN_NAMED_TEST("InsertByKey (RefPtr)", RPTE::InsertByKeyTest)
RUN_NAMED_TEST("FindByKey (unmanaged)", UMTE::FindByKeyTest)
RUN_NAMED_TEST("FindByKey (unique)", UPTE::FindByKeyTest)
RUN_NAMED_TEST("FindByKey (std::uptr)", SUPDDTE::FindByKeyTest)
RUN_NAMED_TEST("FindByKey (std::uptr<Del>)", SUPCDTE::FindByKeyTest)
RUN_NAMED_TEST("FindByKey (RefPtr)", RPTE::FindByKeyTest)
RUN_NAMED_TEST("EraseByKey (unmanaged)", UMTE::EraseByKeyTest)
RUN_NAMED_TEST("EraseByKey (unique)", UPTE::EraseByKeyTest)
RUN_NAMED_TEST("EraseByKey (std::uptr)", SUPDDTE::EraseByKeyTest)
RUN_NAMED_TEST("EraseByKey (std::uptr<Del>)", SUPCDTE::EraseByKeyTest)
RUN_NAMED_TEST("EraseByKey (RefPtr)", RPTE::EraseByKeyTest)
RUN_NAMED_TEST("InsertOrFind (unmanaged)", UMTE::InsertOrFindTest)
RUN_NAMED_TEST("InsertOrFind (unique)", UPTE::InsertOrFindTest)
RUN_NAMED_TEST("InsertOrFind (std::uptr)", SUPDDTE::InsertOrFindTest)
RUN_NAMED_TEST("InsertOrFind (std::uptr<Del>)", SUPCDTE::InsertOrFindTest)
RUN_NAMED_TEST("InsertOrFind (RefPtr)", RPTE::InsertOrFindTest)
RUN_NAMED_TEST("InsertOrReplace (unmanaged)", UMTE::InsertOrReplaceTest)
RUN_NAMED_TEST("InsertOrReplace (unique)", UPTE::InsertOrReplaceTest)
RUN_NAMED_TEST("InsertOrReplace (std::uptr)", SUPDDTE::InsertOrReplaceTest)
RUN_NAMED_TEST("InsertOrReplace (std::uptr<Del>)", SUPCDTE::InsertOrReplaceTest)
RUN_NAMED_TEST("InsertOrReplace (RefPtr)", RPTE::InsertOrReplaceTest)
END_TEST_CASE(hashtable_dll_tests);
} // namespace intrusive_containers
} // namespace tests
} // namespace fbl