diff --git a/src/common/intrusive_list.h b/src/common/intrusive_list.h index 08184381..084e57e3 100644 --- a/src/common/intrusive_list.h +++ b/src/common/intrusive_list.h @@ -8,6 +8,7 @@ #include #include +#include #include "common/assert.h" #include "common/common_types.h" @@ -15,10 +16,8 @@ namespace Dynarmic { namespace Common { -template class IntrusiveListNode; template class IntrusiveList; template class IntrusiveListIterator; -template class IntrusiveListConstIterator; template class IntrusiveListNode { @@ -34,7 +33,8 @@ public: private: friend class IntrusiveList; friend class IntrusiveListIterator; - friend class IntrusiveListConstIterator; + friend class IntrusiveListIterator; + IntrusiveListNode* next = this; IntrusiveListNode* prev = this; }; @@ -97,14 +97,11 @@ public: IntrusiveListIterator erase(const IntrusiveListIterator&); IntrusiveListIterator iterator_to(T&); - IntrusiveListConstIterator begin() const; - IntrusiveListConstIterator end() const; - IntrusiveListConstIterator iterator_to(T&) const; + IntrusiveListIterator begin() const; + IntrusiveListIterator end() const; + IntrusiveListIterator iterator_to(T&) const; private: - friend class IntrusiveListIterator; - friend class IntrusiveListConstIterator; - void AddAfter(IntrusiveListNode* existing_node, IntrusiveListNode* new_node) { new_node->next = existing_node->next; new_node->prev = existing_node; @@ -125,11 +122,26 @@ private: template class IntrusiveListIterator { public: + using iterator_category = std::bidirectional_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = T; + using pointer = value_type*; + using const_pointer = const value_type*; + using reference = value_type&; + using const_reference = const value_type&; + + // If value_type is const, we want "const IntrusiveListNode", not "const IntrusiveListNode" + using node_type = std::conditional_t::value, + const IntrusiveListNode>, + IntrusiveListNode>; + using node_pointer = node_type*; + using node_reference = node_type&; + IntrusiveListIterator() = default; IntrusiveListIterator(const IntrusiveListIterator& other) = default; IntrusiveListIterator& operator=(const IntrusiveListIterator& other) = default; - IntrusiveListIterator(IntrusiveList* list, IntrusiveListNode* node) : root(list->root.get()), node(node) { + IntrusiveListIterator(node_pointer list_root, node_pointer node) : root(list_root), node(node) { } IntrusiveListIterator& operator++() { @@ -159,89 +171,29 @@ public: return !(*this == other); } - const T& operator*() const { + reference operator*() const { DEBUG_ASSERT(node != root); - return *reinterpret_cast(node); + return static_cast(*node); } - T& operator*() { + pointer operator->() const { DEBUG_ASSERT(node != root); - return *reinterpret_cast(node); - } - T* operator->() { - DEBUG_ASSERT(node != root); - return reinterpret_cast(node); - } - const T* operator->() const { - DEBUG_ASSERT(node != root); - return reinterpret_cast(node); + return std::addressof(operator*()); } private: friend class IntrusiveList; - IntrusiveListNode* root = nullptr; - IntrusiveListNode* node = nullptr; -}; - -template -class IntrusiveListConstIterator { -public: - IntrusiveListConstIterator() = default; - IntrusiveListConstIterator(const IntrusiveListConstIterator& other) = default; - IntrusiveListConstIterator& operator=(const IntrusiveListConstIterator& other) = default; - - IntrusiveListConstIterator(const IntrusiveList* list, IntrusiveListNode* node) : root(list->root.get()), node(node) { - } - - IntrusiveListConstIterator& operator++() { - node = node == root ? node : node->next; - return *this; - } - IntrusiveListConstIterator operator++(int) { - IntrusiveListConstIterator it(*this); - node = node == root ? node : node->next; - return it; - } - IntrusiveListConstIterator& operator--() { - node = node->prev == root ? node : node->prev; - return *this; - } - IntrusiveListConstIterator operator--(int) { - IntrusiveListConstIterator it(*this); - node = node->prev == root ? node : node->prev; - return it; - } - - bool operator==(const IntrusiveListConstIterator& other) const { - DEBUG_ASSERT(root == other.root); - return node == other.node; - } - bool operator!=(const IntrusiveListConstIterator& other) const { - return !(*this == other); - } - - const T& operator*() const { - DEBUG_ASSERT(node != root); - return *reinterpret_cast(node); - } - const T* operator->() const { - DEBUG_ASSERT(node != root); - return reinterpret_cast(node); - } - -private: - friend class IntrusiveList; - IntrusiveListNode* root = nullptr; - IntrusiveListNode* node = nullptr; + node_pointer root = nullptr; + node_pointer node = nullptr; }; template IntrusiveListIterator IntrusiveList::begin() { - return IntrusiveListIterator(this, root->next); + return IntrusiveListIterator(root.get(), root->next); } template IntrusiveListIterator IntrusiveList::end() { - return IntrusiveListIterator(this, root.get()); + return IntrusiveListIterator(root.get(), root.get()); } template @@ -256,22 +208,22 @@ IntrusiveListIterator IntrusiveList::erase(const IntrusiveListIterator& template IntrusiveListIterator IntrusiveList::iterator_to(T& item) { - return IntrusiveListIterator(this, static_cast*>(&item)); + return IntrusiveListIterator(root.get(), static_cast*>(&item)); } template -IntrusiveListConstIterator IntrusiveList::begin() const { - return IntrusiveListConstIterator(this, root->next); +IntrusiveListIterator IntrusiveList::begin() const { + return IntrusiveListIterator(root.get(), root->next); } template -IntrusiveListConstIterator IntrusiveList::end() const { - return IntrusiveListConstIterator(this, root.get()); +IntrusiveListIterator IntrusiveList::end() const { + return IntrusiveListIterator(root.get(), root.get()); } template -IntrusiveListConstIterator IntrusiveList::iterator_to(T& item) const { - return IntrusiveListConstIterator(this, static_cast*>(&item)); +IntrusiveListIterator IntrusiveList::iterator_to(T& item) const { + return IntrusiveListIterator(root.get(), static_cast*>(&item)); } } // namespace Common