#include #include template class threadsafe_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: threadsafe_list() {} ~threadsafe_list() { remove_if([](T const&){return true;}); } threadsafe_list(threadsafe_list const& other)=delete; threadsafe_list& operator=(threadsafe_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_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); 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); } } } };