intrusive_list: Support inserters

Allows std::inserter, std::back_inserter, and std::front_inserter to work
with intrusive lists.
This commit is contained in:
Lioncash 2016-08-18 21:13:14 -04:00 committed by MerryMage
parent 36a0ad5bc2
commit 23d190f7b0
2 changed files with 27 additions and 38 deletions

View file

@ -54,38 +54,37 @@ public:
using reverse_iterator = std::reverse_iterator<iterator>; using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>;
/**
* Inserts a node at the given location indicated by an iterator.
*
* @param location The location to insert the node.
* @param new_node The node to add.
*/
iterator insert(iterator location, pointer new_node) {
auto existing_node = location.AsNodePointer();
new_node->next = existing_node;
new_node->prev = existing_node->prev;
existing_node->prev->next = new_node;
existing_node->prev = new_node;
return iterator(root.get(), new_node);
}
/** /**
* Add an entry to the start of the list. * Add an entry to the start of the list.
* @param node Node to add to the list. * @param node Node to add to the list.
*/ */
void Prepend(reference node) { void push_front(pointer node) {
AddAfter(root.get(), &node); insert(begin(), node);
} }
/** /**
* Add an entry to the end of the list * Add an entry to the end of the list
* @param node Node to add to the list. * @param node Node to add to the list.
*/ */
void Append(reference node) { void push_back(pointer node) {
AddBefore(root.get(), &node); insert(end(), node);
}
/**
* Add an entry after an existing node in this list
* @param existing_node Node to add new_node after. Must already be member of the list.
* @param new_node Node to add to the list.
*/
void AddAfter(reference existing, reference node) {
AddAfter(&existing, &node);
}
/**
* Add an entry before an existing node in this list
* @param existing_node Node to add new_node before. Must already be member of the list.
* @param new_node Node to add to the list.
*/
void AddBefore(reference existing, reference node) {
AddBefore(&existing, &node);
} }
/** /**
@ -133,20 +132,6 @@ public:
} }
private: private:
void AddAfter(IntrusiveListNode<T>* existing_node, IntrusiveListNode<T>* new_node) {
new_node->next = existing_node->next;
new_node->prev = existing_node;
existing_node->next->prev = new_node;
existing_node->next = new_node;
}
void AddBefore(IntrusiveListNode<T>* existing_node, IntrusiveListNode<T>* new_node) {
new_node->next = existing_node;
new_node->prev = existing_node->prev;
existing_node->prev->next = new_node;
existing_node->prev = new_node;
}
std::shared_ptr<IntrusiveListNode<T>> root = std::make_shared<IntrusiveListNode<T>>(); std::shared_ptr<IntrusiveListNode<T>> root = std::make_shared<IntrusiveListNode<T>>();
}; };
@ -211,6 +196,10 @@ public:
return std::addressof(operator*()); return std::addressof(operator*());
} }
node_pointer AsNodePointer() const {
return node;
}
private: private:
friend class IntrusiveList<T>; friend class IntrusiveList<T>;
node_pointer root = nullptr; node_pointer root = nullptr;

View file

@ -515,7 +515,7 @@ IR::Value IREmitter::Inst(IR::Opcode op, std::initializer_list<IR::Value> args)
index++; index++;
}); });
block.instructions.Append(*inst); block.instructions.push_back(inst);
return IR::Value(inst); return IR::Value(inst);
} }