#include #include #include #include template class list { struct node { std::mutex m; std::shared_ptr data; std::unique_ptr next; node() : next() {} node(T const& value) : data(std::make_shared(value)) {} }; node head; public: list() {} ~list() { remove_if([](T const&) { return true; }); } list(list const& other) = delete; list& operator=(list const& other) = delete; void push_front(T const& value) { std::unique_ptr new_node(new node(value)); std::lock_guard lk(head.m); new_node->next = std::move(head.next); head.next = std::move(new_node); } template void for_each(Function f) { node* current = &head; std::unique_lock lk(head.m); while (node* const next = current->next.get()) { std::unique_lock next_lk(next->m); lk.unlock(); f(*next->data); current = next; lk = std::move(next_lk); } } template std::shared_ptr find_first_of(Predicate p) { node* current = &head; std::unique_lock lk(head.m); while (node* const next = current->next.get()) { std::unique_lock next_lk(next->m); lk.unlock(); if (p(*next->data)) { return next->data; } current = next; lk = std::move(next_lk); } return std::shared_ptr(); } template void remove_if(Predicate p) { node* current = &head; std::unique_lock lk(head.m); while (node* const next = current->next.get()) { std::unique_lock next_lk(next->m); if (p(*next->data)) { std::unique_ptr old_next = std::move(current->next); current->next = std::move(next->next); next_lk.unlock(); } else { lk.unlock(); current = next; lk = std::move(next_lk); } } } }; void push(list* l) { for (int i = 0; i < 10; ++i) { printf("pushing %d\n", i); l->push_front(i); } } void visit(int i) { printf("visit %d\n", i); } int main() { list l; std::thread t(push, &l); sleep(1); l.for_each(visit); t.join(); return 0; }